Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5f86aed17d | ||
|
|
99bd1fc8d5 | ||
|
|
70f2f9f1b7 | ||
|
|
cf9e33a4e4 | ||
|
|
c07d6f9c49 | ||
|
|
503a559b2a | ||
|
|
2dac3d1128 | ||
|
|
d7d87fed76 | ||
|
|
c08349517b | ||
|
|
f3774b5987 | ||
|
|
dccc7345ab | ||
|
|
7e51fb8371 | ||
|
|
0d7c9ac091 | ||
|
|
aee34fce32 | ||
|
|
c29d306d10 | ||
|
|
a5edc8071c | ||
|
|
106a673ba8 | ||
|
|
99fe01a0d6 | ||
|
|
94e496c77e | ||
|
|
5a9a694050 | ||
|
|
68c8046a55 | ||
|
|
c3fae61dda | ||
|
|
b783e5fa63 | ||
|
|
869a4e68a4 | ||
|
|
2ad827dfb9 | ||
|
|
fa745f2cfe | ||
|
|
e8cc443681 | ||
|
|
97fc6a10a4 | ||
|
|
d0218bfe54 | ||
|
|
b8b7ff882d | ||
|
|
c17b6a8821 | ||
|
|
2b489bae26 | ||
|
|
a9d4bf4a25 | ||
|
|
0d618efd0d | ||
|
|
5b0697b68c | ||
|
|
725b5f7932 | ||
|
|
2945d4ce08 | ||
|
|
14ff1451ce | ||
|
|
27716597d5 | ||
|
|
fd86520e91 | ||
|
|
815ed8e768 | ||
|
|
08f61b33f0 | ||
|
|
cb8f37bd2a | ||
|
|
b13277c156 | ||
|
|
b4438bbdfb | ||
|
|
5af711465d | ||
|
|
32cbad389a | ||
|
|
6022578901 | ||
|
|
740acf3664 | ||
|
|
46e07b2ec3 | ||
|
|
0318db838e | ||
|
|
04400b0d18 | ||
|
|
69c5572161 | ||
|
|
0d63932eab | ||
|
|
bb6c120691 | ||
|
|
e657f745f4 | ||
|
|
9a1c9173a3 | ||
|
|
dc648a5368 | ||
|
|
84651210e6 | ||
|
|
054183b73a | ||
|
|
d0612752f0 | ||
|
|
c3a1810890 | ||
|
|
51de6abbed | ||
|
|
94f4a239cc | ||
|
|
14a23268ad | ||
|
|
35a9bfe025 | ||
|
|
212bf3e96e | ||
|
|
9021a7ceec | ||
|
|
b56cf08319 | ||
|
|
a09ef9576d | ||
|
|
ea70bbc1b6 | ||
|
|
6fce88d93a | ||
|
|
82edb8cdf1 | ||
|
|
5ba70e05fc | ||
|
|
5c036059f8 | ||
|
|
a3c52ca679 | ||
|
|
f8138974c1 | ||
|
|
08908a5511 | ||
|
|
50df3e415d | ||
|
|
b3b385dd06 | ||
|
|
1047e9096a | ||
|
|
772afe4b5b | ||
|
|
6a791267a0 | ||
|
|
e9b7e13be1 | ||
|
|
516d64a1ff | ||
|
|
af7079f708 | ||
|
|
93502bb64b | ||
|
|
0b74716668 | ||
|
|
61a8f2adea | ||
|
|
4d9701613f | ||
|
|
90ab359ed3 | ||
|
|
8ef234dacf | ||
|
|
ea82ae5090 | ||
|
|
65aa347a9f | ||
|
|
3ba6d78241 | ||
|
|
0e2bb55483 | ||
|
|
c0b64f4bae | ||
|
|
6d70c0889d | ||
|
|
22a614bbf4 | ||
|
|
1fec5622b6 | ||
|
|
a1e2651b4c | ||
|
|
ec498ec476 | ||
|
|
e433ad319e | ||
|
|
30f9d01df9 | ||
|
|
579b592c12 | ||
|
|
dfbab9a7c0 | ||
|
|
d1730258bf | ||
|
|
1afd3e821a | ||
|
|
9e36b0fdc7 | ||
|
|
857637c1fb | ||
|
|
40854f6edb | ||
|
|
7f403b8050 | ||
|
|
2a59199870 | ||
|
|
6712d8c844 | ||
|
|
856da09741 | ||
|
|
c4cf410a59 | ||
|
|
0994dd4070 | ||
|
|
6cddce9f15 | ||
|
|
ac44fd59e3 | ||
|
|
5c25f9270c | ||
|
|
bfe301ae1c | ||
|
|
29aa64092a | ||
|
|
d9a0041870 | ||
|
|
ea3787e393 | ||
|
|
de2fe7f6be | ||
|
|
c548d1f2d8 | ||
|
|
fbe726e4c4 | ||
|
|
208ac286f8 | ||
|
|
9aef419c4c | ||
|
|
a2c6490d31 | ||
|
|
4b399995f5 | ||
|
|
877bb1f91f | ||
|
|
cd696e60ab | ||
|
|
9bd5a518ea | ||
|
|
fe4cc4b01d | ||
|
|
65d568c283 | ||
|
|
a118f110fa | ||
|
|
f803f29158 | ||
|
|
954c2d32c1 | ||
|
|
5112251894 | ||
|
|
545769885d | ||
|
|
94ea82c10a | ||
|
|
a6c978573f | ||
|
|
31d70dae49 | ||
|
|
9a639b40b7 | ||
|
|
e84f47abc8 | ||
|
|
741e4b0b30 | ||
|
|
52a720ec33 | ||
|
|
416c61a663 | ||
|
|
23bd296aeb | ||
|
|
2c8843fc86 | ||
|
|
aa07373c4e | ||
|
|
a3b5a44f79 | ||
|
|
d5fad8db39 | ||
|
|
ef5d703682 | ||
|
|
40efaf848e | ||
|
|
575854c8b9 | ||
|
|
3299947cc1 | ||
|
|
9daeea7400 | ||
|
|
4e51afc36c | ||
|
|
f1f333dc7a | ||
|
|
69a56ced7a | ||
|
|
2c468b0bb2 | ||
|
|
c67248ffc7 | ||
|
|
60936080da | ||
|
|
4db04564a9 | ||
|
|
f6b0ddc0b3 | ||
|
|
b42399e9a9 | ||
|
|
ba72056bf2 | ||
|
|
b8e4a51228 | ||
|
|
0b12f7db42 | ||
|
|
5053cffdad | ||
|
|
02f852604f | ||
|
|
e4ab8c56a0 | ||
|
|
86016d41d7 | ||
|
|
3fdfd07443 | ||
|
|
d801cdd722 | ||
|
|
72e5078ce9 | ||
|
|
a7c3f3dd35 | ||
|
|
729fc10674 | ||
|
|
12f0312b00 | ||
|
|
8c0e3e9dad | ||
|
|
c7104f0c0d | ||
|
|
679638beb2 | ||
|
|
f8fc5844b1 | ||
|
|
d86d8cf65a | ||
|
|
11e5b5fe95 | ||
|
|
42b623e9b0 | ||
|
|
21e65b8742 | ||
|
|
c6ac4d11be | ||
|
|
2d48e07139 | ||
|
|
3fee341ac2 | ||
|
|
2bed6776e4 | ||
|
|
01e0290d6e | ||
|
|
1c61154206 | ||
|
|
addf25ff16 | ||
|
|
578c1613d1 | ||
|
|
6073445551 | ||
|
|
30763684b7 | ||
|
|
ace8f44f59 | ||
|
|
98994bbeaa | ||
|
|
b089303505 | ||
|
|
8992e98c8d | ||
|
|
205245f269 | ||
|
|
b375041790 | ||
|
|
3a41665302 | ||
|
|
f6686b8188 | ||
|
|
31b43cf3c7 | ||
|
|
e483b19c14 | ||
|
|
50b400a1f8 | ||
|
|
d90dc35dd3 | ||
|
|
b45970b3b6 | ||
|
|
a5700cc914 | ||
|
|
d3c59cbff3 | ||
|
|
8bc1cc28d0 | ||
|
|
1ad9c321bc | ||
|
|
c9dede08d4 | ||
|
|
3b721112e6 | ||
|
|
0093fb8276 | ||
|
|
fe8137521a | ||
|
|
2bc7a1bb10 | ||
|
|
120ba0ba9a | ||
|
|
88d93737aa | ||
|
|
317d5a3aba | ||
|
|
ddc5cb0224 |
+18
-3
@@ -5,7 +5,7 @@ AUTOMAKE_OPTIONS = subdir-objects
|
||||
SUBDIRS = po
|
||||
|
||||
bin_PROGRAMS = pv
|
||||
dist_doc_DATA = README.md docs/INSTALL docs/COPYING docs/NEWS.md docs/ACKNOWLEDGEMENTS.md docs/DEVELOPERS.md docs/TODO.md docs/benchmark.sh
|
||||
dist_doc_DATA = README.md docs/INSTALL docs/COPYING docs/NEWS.md docs/ACKNOWLEDGEMENTS.md docs/DEVELOPERS.md docs/benchmark.sh
|
||||
dist_man1_MANS = docs/pv.1
|
||||
|
||||
EXTRA_DIST = docs/pv.1.md
|
||||
@@ -17,12 +17,14 @@ src/main/main.c \
|
||||
src/main/options.c \
|
||||
src/main/remote.c \
|
||||
src/main/version.c \
|
||||
src/pv/calc.c \
|
||||
src/pv/cursor.c \
|
||||
src/pv/display.c \
|
||||
src/pv/elapsedtime.c \
|
||||
src/pv/file.c \
|
||||
src/pv/loop.c \
|
||||
src/pv/number.c \
|
||||
src/pv/proctitle.c \
|
||||
src/pv/signal.c \
|
||||
src/pv/state.c \
|
||||
src/pv/string.c \
|
||||
@@ -69,8 +71,10 @@ tests/Integrity_-_Large_file_support.test \
|
||||
tests/Integrity_-_On_output_pipe_close.test \
|
||||
tests/Integrity_-_When_adjusted_remotely.test \
|
||||
tests/Memory_safety_-_Basic.test \
|
||||
tests/Memory_safety_-_Process_title.test \
|
||||
tests/Memory_safety_-_Remote_control_receiver.test \
|
||||
tests/Memory_safety_-_Remote_control_sender.test \
|
||||
tests/Memory_safety_-_Watchfd.test \
|
||||
tests/Modifiers_-_--direct-io.test \
|
||||
tests/Modifiers_-_--force.test \
|
||||
tests/Modifiers_-_--interval.test \
|
||||
@@ -81,13 +85,15 @@ tests/Modifiers_-_--sync.test \
|
||||
tests/Terminal_-_Detect_width.test \
|
||||
tests/Transfer_-_--rate-limit.test \
|
||||
tests/Transfer_-_--remote.test \
|
||||
tests/Transfer_-_--stop-at-size.test
|
||||
tests/Transfer_-_--stop-at-size.test \
|
||||
tests/Watchfd_-_Multiple_descriptors.test \
|
||||
tests/Watchfd_-_Single_descriptor.test
|
||||
|
||||
EXTRA_DIST += $(TESTS) tests/run-valgrind.sh tests/test-env.sh
|
||||
|
||||
docs/pv.1.md: $(srcdir)/docs/pv.1
|
||||
test -d docs || mkdir docs
|
||||
pandoc --from man --to markdown < $< | sed '/\*\*\*\*/{s/\*//g;s/^/**/;s/$$/**/}' | sed '/^```/,/^```/d' > $@
|
||||
pandoc --from man --to markdown < $< | sed '/\*\*\*\*/{s/\*//g;s/^/**/;s/$$/**/}' | sed '/^```/,/^```/d' | sed 's/^\\\[/[/' > $@
|
||||
|
||||
SUFFIXES = .c .o .e
|
||||
|
||||
@@ -112,6 +118,15 @@ clean-local:
|
||||
# Convenience alias for "make check": "make test"
|
||||
test: check
|
||||
|
||||
# Generate a package manifest if MAINTAINER is set.
|
||||
dist-hook:
|
||||
if test -n "$(MAINTAINER)"; then \
|
||||
cd "$(top_distdir)" \
|
||||
&& { printf "%s\n\n" "Check file integrity with 'sha512sum -c MANIFEST && echo OK'."; \
|
||||
find -type f -not -name MANIFEST -exec sha512sum '{}' ';' | sort -k 2; } \
|
||||
| gpg -u "$(MAINTAINER)" --clearsign > MANIFEST; \
|
||||
else true; fi
|
||||
|
||||
# "release" target - requires MAINTAINER variable to select GPG key.
|
||||
release: distcheck
|
||||
gpg --list-secret-keys 2>&1 | grep -F 'uid' | grep -Fq "$(MAINTAINER)"
|
||||
|
||||
@@ -12,28 +12,46 @@ completion it is, and an estimate of how long it will be until completion.
|
||||
A manual page is included in this distribution ("`man pv`"). Before
|
||||
installation, it is in "[docs/pv.1](./docs/pv.1.md)".
|
||||
|
||||
Changes are listed in "[docs/NEWS.md](./docs/NEWS.md)". The to-do list is "[docs/TODO.md](./docs/TODO.md)".
|
||||
Changes are listed in "[docs/NEWS.md](./docs/NEWS.md)".
|
||||
|
||||
Developers and translators, please see "[docs/DEVELOPERS.md](./docs/DEVELOPERS.md)".
|
||||
|
||||
Translators can use the Weblate instance hosted by Codeberg:
|
||||
[https://translate.codeberg.org/engage/pv/](https://translate.codeberg.org/engage/pv/)
|
||||
|
||||
# Compilation
|
||||
[](https://translate.codeberg.org/engage/pv/)
|
||||
|
||||
To compile the package, type "`sh ./configure`", which should generate a
|
||||
Makefile for your system. You may then type "`make`" to build everything,
|
||||
and "`make install`" to install it.
|
||||
If you don't see your language listed, raise an issue on the issue tracker
|
||||
(or just email the maintainer) asking for it to be added.
|
||||
|
||||
See the file "[docs/INSTALL](./docs/INSTALL)" for more about the _configure_ script.
|
||||
|
||||
If this is not a packaged release, you will need the GNU build system tools
|
||||
(`autoconf`, `aclocal`, `autopoint`, `automake`) and the `gettext`
|
||||
development tools. You can then run "`autoreconf -is`" to generate the
|
||||
"`configure`" script.
|
||||
# Installation
|
||||
|
||||
See "[docs/INSTALL](./docs/INSTALL)" for more about the _configure_ script.
|
||||
|
||||
The typical process for a system-wide install is:
|
||||
|
||||
sh ./configure --prefix=/usr
|
||||
make
|
||||
sudo make install
|
||||
|
||||
This requires the build toolchain ("`sudo apt install build-essential`" on
|
||||
Debian or Ubuntu systems).
|
||||
|
||||
If this is not a packaged release, the _configure_ script is not included.
|
||||
It is generated with the GNU build system tools (_autoconf_, _aclocal_,
|
||||
_autopoint_, _automake_); _gettext_ is also needed. On Debian or Ubuntu,
|
||||
run "`sudo apt install automake autopoint gettext`". Once those tools are
|
||||
in place, call "`autoreconf -is`" to generate the _configure_ script, and
|
||||
run it as described above.
|
||||
|
||||
|
||||
# Copyright, bug reporting, and acknowledgements
|
||||
|
||||
Copyright (C) 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood.
|
||||
See "[docs/ACKNOWLEDGEMENTS.md](./docs/ACKNOWLEDGEMENTS.md)" for a list of
|
||||
contributors.
|
||||
|
||||
Copyright (C) 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2024 Andrew Wood.
|
||||
|
||||
License GPLv3+: GNU GPL version 3 or later <https://www.gnu.org/licenses/gpl-3.0.html>.
|
||||
|
||||
@@ -56,10 +74,8 @@ from the **pv** home page.
|
||||
|
||||
The **pv** home page is at:
|
||||
|
||||
[https://www.ivarch.com/programs/pv.shtml](https://www.ivarch.com/programs/pv.shtml)
|
||||
> [https://www.ivarch.com/programs/pv.shtml](https://www.ivarch.com/programs/pv.shtml)
|
||||
|
||||
The latest version can always be found here.
|
||||
|
||||
**Please see "[docs/ACKNOWLEDGEMENTS.md](./docs/ACKNOWLEDGEMENTS.md)" for a list of contributors.**
|
||||
|
||||
---
|
||||
|
||||
+49
-3
@@ -1,10 +1,10 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
dnl
|
||||
dnl Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood
|
||||
dnl Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2024 Andrew Wood
|
||||
dnl
|
||||
dnl License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
|
||||
AC_INIT([pv], [1.8.5], [pv@ivarch.com], [pv], [https://www.ivarch.com/programs/pv.shtml])
|
||||
AC_INIT([pv], [1.9.7], [pv@ivarch.com], [pv], [https://www.ivarch.com/programs/pv.shtml])
|
||||
AC_CONFIG_SRCDIR([src/include/config.h.in])
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
AC_CONFIG_HEADERS([src/include/config.h])
|
||||
@@ -29,6 +29,8 @@ AC_CHECK_FUNCS([vsnprintf strlcat strtoul memrchr])
|
||||
AC_CHECK_FUNCS([fdatasync])
|
||||
AC_CHECK_FUNCS([fpathconf sysconf posix_memalign posix_fadvise])
|
||||
AC_CHECK_FUNCS([nanosleep])
|
||||
AC_CHECK_FUNCS([setitimer])
|
||||
AC_CHECK_FUNCS([setproctitle])
|
||||
AC_CHECK_HEADERS([getopt.h])
|
||||
AC_CHECK_HEADERS([limits.h])
|
||||
AC_CHECK_HEADERS([wctype.h])
|
||||
@@ -36,13 +38,18 @@ AC_CHECK_HEADERS([termios.h])
|
||||
AC_CHECK_HEADERS([libgen.h])
|
||||
AC_CHECK_HEADERS([sys/ioctl.h])
|
||||
AC_CHECK_HEADERS([libintl.h locale.h])
|
||||
AC_CHECK_HEADERS([sys/sysmacros.h])
|
||||
AC_CHECK_MEMBERS([struct stat.st_blksize])
|
||||
|
||||
AC_SEARCH_LIBS([sqrtl],[m])
|
||||
AC_CHECK_HEADERS([math.h])
|
||||
AC_CHECK_FUNCS([sqrtl])
|
||||
|
||||
dnl Libraries that may contain key functions.
|
||||
AC_SEARCH_LIBS([clock_gettime],[rt])
|
||||
|
||||
dnl Items we can't do without.
|
||||
AC_CHECK_FUNCS([alarm basename clock_gettime dup2 getcwd memcpy memmove memset select setlocale strchr strerror strrchr strstr], [], [AC_MSG_ERROR([required function is missing])])
|
||||
AC_CHECK_FUNCS([alarm basename clock_gettime dup2 getcwd memcpy memmove memset mkdir select setlocale strchr strerror strrchr strstr], [], [AC_MSG_ERROR([required function is missing])])
|
||||
AC_CHECK_HEADERS([fcntl.h sys/file.h sys/time.h unistd.h], [], [AC_MSG_ERROR([required header file is missing])])
|
||||
|
||||
dnl Make sure all the types we use are defined.
|
||||
@@ -54,6 +61,45 @@ AC_TYPE_SIZE_T
|
||||
AC_TYPE_SSIZE_T
|
||||
AC_TYPE_UID_T
|
||||
|
||||
AC_CHECK_MEMBERS([struct stat.st_rdev])
|
||||
|
||||
dnl Check whether a signal handler can see the PID of the sender.
|
||||
AC_MSG_CHECKING([siginfo_t provides a signal sender's PID])
|
||||
AC_RUN_IFELSE(
|
||||
[AC_LANG_PROGRAM([[
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static pid_t signalSender = 0;
|
||||
|
||||
#ifdef SA_SIGINFO
|
||||
static void receiveUSR2( __attribute__((unused))
|
||||
int sig, siginfo_t * info, __attribute__((unused))
|
||||
void *ucontext)
|
||||
{
|
||||
if (NULL != info)
|
||||
signalSender = info->si_pid;
|
||||
}
|
||||
#endif
|
||||
]], [[
|
||||
struct sigaction sa;
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
#ifdef SA_SIGINFO
|
||||
sa.sa_sigaction = receiveUSR2;
|
||||
(void) sigemptyset(&(sa.sa_mask));
|
||||
sa.sa_flags = SA_SIGINFO;
|
||||
(void) sigaction(SIGUSR2, &sa, NULL);
|
||||
raise(SIGUSR2);
|
||||
#endif
|
||||
return signalSender == 0 ? 1 : 0;
|
||||
]])], [
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE([SIGINFO_PROVIDES_PID], [1], [Signal handlers can determine the sending PID])
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
|
||||
AH_BOTTOM([#include "config-aux.h"])
|
||||
|
||||
AC_ARG_ENABLE([debugging],
|
||||
|
||||
+60
-28
@@ -12,18 +12,18 @@ is acknowledged and greatly appreciated:
|
||||
* Joshua Jensen - reported RPM installation bug
|
||||
* Boris Folgmann <http://www.folgmann.com/en/> - reported cursor handling bug
|
||||
* Mathias Gumz - reported NLS bug
|
||||
* Daniel Roethlisberger - submitted patch to use lockfiles for "`-c`" if terminal locking fails
|
||||
* Adam Buchbinder - lots of help with a Cygwin port of "`-c`"
|
||||
* Mark Tomich <http://metuchen.dyndns.org> - suggested "`-B`" option
|
||||
* Daniel Roethlisberger - submitted patch to use lockfiles for **-c** if terminal locking fails
|
||||
* Adam Buchbinder - lots of help with a Cygwin port of **-c**
|
||||
* Mark Tomich <http://metuchen.dyndns.org> - suggested **-B** option
|
||||
* Gert Menke - reported bug when piping to `dd` with a large input buffer size
|
||||
* Ville Herva <Ville.Herva@iki.fi> - informative bug report about rate limiting performance
|
||||
* Elias Pipping - patch to compile properly on Darwin 9; potential NULL deref report
|
||||
* Patrick Collison - similar patch for OS X
|
||||
* Boris Lohner - reported problem that "`-L`" does not complain if given non-numeric value
|
||||
* Boris Lohner - reported problem that **-L** does not complain if given non-numeric value
|
||||
* Sebastian Kayser - supplied testing for *SIGPIPE*, demonstrated internationalisation problem
|
||||
* Laszlo Ersek <http://phptest11.atw.hu/> - reported shared memory leak on *SIGINT* with "`-c`"
|
||||
* Laszlo Ersek <http://phptest11.atw.hu/> - reported shared memory leak on *SIGINT* with **-c**
|
||||
* Phil Rutschman <http://bandgap.rsnsoft.com/> - provided a patch for fully restoring terminal state on exit
|
||||
* Henry Precheur <http://henry.precheur.org/> - reporting and suggestions for "`--rate-limit`" bug when rate is under 10
|
||||
* Henry Precheur <http://henry.precheur.org/> - reporting and suggestions for **--rate-limit** bug when rate is under 10
|
||||
* E. Rosten <http://mi.eng.cam.ac.uk/~er258/> - supplied patch for block buffering in line mode
|
||||
* Kjetil Torgrim Homme - reported compilation error with default *CFLAGS* on non-GCC compilers
|
||||
* Alexandre de Verteuil - reported bug in OS X build and supplied test environment to fix in
|
||||
@@ -31,63 +31,95 @@ is acknowledged and greatly appreciated:
|
||||
* Sam Nelson <http://www.siliconfuture.net/> - supplied patch to fix trailing slash on *DESTDIR*
|
||||
* Daniel Pape - reported Cygwin installation problem due to *DESTDIR*
|
||||
* Philipp Beckers - ported to the Syabas PopcornHour A-100 series
|
||||
* Henry Gebhard <hsggebhardt@googlemail.com> - supplied patches to improve SI prefixes and add "`--average-rate`"
|
||||
* Henry Gebhard <hsggebhardt@googlemail.com> - supplied patches to improve SI prefixes and add **--average-rate**
|
||||
* Vladimir Kokarev, Alexander Leo - reported that exit status did not reflect file errors
|
||||
* Thomas Rachel - submitted patches for IEEE1541 (MiB suffixes), 1+e03 bug
|
||||
* Guillaume Marcais - submitted speedup patch for line mode
|
||||
* Moritz Barsnick - submitted patch for compile warning in size calculation
|
||||
* Pawel Piatek - submitted RPM and patches for AIX
|
||||
* Sami Liedes - submitted patch for "`--timer`" and "`--bytes`" with "`--numeric`"
|
||||
* Steven Willis - reported problem with "`-R`" killing non-PV remote processes
|
||||
* Vladimir Pal, Vladimir Ermakov - submitted patch which led to development of "`--format`" option
|
||||
* Sami Liedes - submitted patch for **--timer** and **--bytes** with **--numeric**
|
||||
* Steven Willis - reported problem with **-R** killing non-PV remote processes
|
||||
* Vladimir Pal, Vladimir Ermakov - submitted patch which led to development of **--format** option
|
||||
* Peter Samuelson <peter@p12n.org> - submitted patch to calculate size if stdout is a block device
|
||||
* Miguel Diaz - much Cygwin help (and packaging), found narrow-terminal bug
|
||||
* Jim Salter <http://ubuntuwiki.net> - commissioned work on the "`--skip-errors`" option
|
||||
* Jim Salter <http://ubuntuwiki.net> - commissioned work on the **--skip-errors** option
|
||||
* Wouter Pronk - reported build problem on SCO
|
||||
* Bryan Dongray <http://www.dongrays.com> - provided patches for test scripts failing on older Red Hats
|
||||
* Zev Weiss <www.bewilderbeest.net> - provided patch to fix `splice()` not using stdin
|
||||
* Zing Shishak - provided patch for "`--null`" / "`-0`" (count null terminated lines)
|
||||
* Jacek Wielemborek <http://deetah.jogger.pl/kategorie/english> - implemented fdwatch in Python, suggested PV port; reported bug with "`-l`" and ETA / size; many other contributions
|
||||
* Zing Shishak - provided patch for **--null** / **-0** (count null terminated lines)
|
||||
* Jacek Wielemborek <http://deetah.jogger.pl/kategorie/english> - implemented fdwatch in Python, suggested PV port; reported bug with **-l** and ETA / size; many other contributions
|
||||
* Kim Krecht - suggested buffer fill status and last bytes output display options
|
||||
* Cristian Ciupitu <http://ciupicri.github.io>, Josh Stone - pointed out file descriptor leak with helpful suggestions (Josh Stone initially noticed the missing close)
|
||||
* Jan Seda - found issue with `splice()` and *SPLICE_F_NONBLOCK* causing slowdown
|
||||
* André Stapf - pointed out formatting problem e.g. 13GB -> 13.1GB which should be shown 13.0GB -> 13.1GB; highlighted on-startup row swapping in "`-c`", and suggested "`--discard`"
|
||||
* Damon Harper <http://www.usrbin.ca/> - suggested "`-D`" / "`--delay-start`" option
|
||||
* André Stapf - pointed out formatting problem e.g. 13GB -> 13.1GB which should be shown 13.0GB -> 13.1GB; highlighted on-startup row swapping in **-c**, and suggested **--discard**; suggested making **--fineta** have a "FIN" prefix
|
||||
* Damon Harper <http://www.usrbin.ca/> - suggested **-D** / **--delay-start** option
|
||||
* Ganaël Laplanche <http://www.martymac.org> - provided patch for `lstat64()` on systems that do not support it
|
||||
* Peter Korsgaard <http://www.buildroot.net/> - provided similar patch for `lstat64()`, specifically for uClibc support; provided AIX cross-compilation patch to fix bug in "`-lc128`" check
|
||||
* Peter Korsgaard <http://www.buildroot.net/> - provided similar patch for `lstat64()`, specifically for uClibc support; provided AIX cross-compilation patch to fix bug in **-lc128** check
|
||||
* Ralf Ramsauer <https://blog.ramses-pyramidenbau.de/> - reported bug which dropped transfer rate on terminal resize
|
||||
* Michiel Van Herwegen - reported and discussed bug with "`-l`" and ETA / size
|
||||
* Erkki Seppälä <http://www.inside.org/~flux/> - provided patch implementing "`-I`"
|
||||
* Michiel Van Herwegen - reported and discussed bug with **-l** and ETA / size
|
||||
* Erkki Seppälä <http://www.inside.org/~flux/> - provided patch implementing **-I**
|
||||
* Eric A. Borisch - provided details of compatibility fix for "`%Lu`" in watchpid code
|
||||
* Jan Venekamp - reported MacOS buffer size interactions with pipes
|
||||
* Matt <https://github.com/lemonsqueeze/pv> - provided "rate-window" patches for rate calculation
|
||||
* [Filippo Valsorda](https://github.com/FiloSottile) - provided patch for stat64 issue on Apple Silicon
|
||||
* Matt Koscica, William Dillon - also reported stat64 issue on Apple Silicon
|
||||
* [Demitri Muna](https://github.com/demitri) - assisted with stat64 patch on Apple Silicon
|
||||
* Norman Rasmussen - suggested "`-c`" with "`-d PID:FD`", reject "`-N`" with "`-d PID`"
|
||||
* Norman Rasmussen - suggested **-c** with **-d PID:FD**, reject **-N** with **-d PID**
|
||||
* Andriy Gapon, Jonathan Elchison - reported bug where "`pv /dev/zero >/dev/null &`" stops immediately
|
||||
* Marcelo Chiesa - reported unused-result warnings when compiling PV 1.6.6
|
||||
* Jered Floyd - provided patches to improve "`--rate-limit`"
|
||||
* Jered Floyd - provided patches to improve **--rate-limit**
|
||||
* Christoph Biedl - provided ETA and dynamic interval patches
|
||||
* Richard Fonfara - provided German translations for "`pv --help`"
|
||||
* Johannes Gerer <http://johannesgerer.com> - suggested that "`-B`" should enable "`-C`"
|
||||
* Johannes Gerer <http://johannesgerer.com> - suggested that **-B** should enable **-C**
|
||||
* Sam James - provided fix for number.c build issue caused by missing stddef.h
|
||||
* Jakub Wilk <jwilk@jwilk.net> - corrected README encoding
|
||||
* Frederik Eaton - reported issue with `<()` shell constructs
|
||||
* [gray](https://github.com/gray) - reported issue with "`--force`" and terminal process groups, and proposed a patch
|
||||
* [gray](https://github.com/gray) - reported issue with **--force** and terminal process groups, and proposed a patch
|
||||
* [Luc Gommans](https://github.com/lgommans) / https://lgms.nl/ - provided a "momentary ETA" patch
|
||||
* [ikasty](https://github.com/ikasty) - added relative filename display to "`--watchfd`"
|
||||
* [ikasty](https://github.com/ikasty) - added relative filename display to **--watchfd**
|
||||
* [Michael Weiß](https://github.com/quitschbo) - corrected behaviour when not attached to a terminal
|
||||
* [christoph-zededa](https://github.com/christoph-zededa) - provided OS X support for "`--watchfd`"
|
||||
* [Dave Beckett](https://github.com/dajobe) - added "`@filename`" syntax to "`--size`", and corrected an autoconf problem with stat64 on OS X
|
||||
* [christoph-zededa](https://github.com/christoph-zededa) - provided OS X support for **--watchfd**
|
||||
* [Dave Beckett](https://github.com/dajobe) - added "`@filename`" syntax to **--size**, and corrected an autoconf problem with stat64 on OS X
|
||||
* [Volodymyr Bychkovyak](https://github.com/vbychkoviak) - provided fix for rate limit behaviour with bursty traffic
|
||||
* [Nick Black](https://nick-black.com) - added "`--bits`" option
|
||||
* [Nick Black](https://nick-black.com) - added **--bits** option
|
||||
* [Andrew Schulman](https://github.com/andrew-schulman) - provided reproducible example of terminal size detection issue in 1.7.17/1.7.18
|
||||
* [fuschia74](https://github.com/fuchsia74) - provided "`--enable-static`" patch for "`configure`"
|
||||
* [fuschia74](https://github.com/fuchsia74) - provided **--enable-static** patch for "`configure`"
|
||||
* [Wilhelm von Thiele](https://github.com/TurtleWilly) - assisted with OS X cleanups ([#73](https://codeberg.org/a-j-wood/pv/issues/73), [#74](https://codeberg.org/a-j-wood/pv/issues/74))
|
||||
* Matějů Miroslav, Ing. - suggested fix for ETA and elapsed time faults when suspending and resuming a machine ([#13](https://codeberg.org/a-j-wood/pv/issues/13))
|
||||
* Anthony DeRobertis - suggested the "`--error-skip-block`" option ([#37](https://codeberg.org/a-j-wood/pv/issues/37))
|
||||
* Anthony DeRobertis - suggested the **--error-skip-block** option ([#37](https://codeberg.org/a-j-wood/pv/issues/37))
|
||||
* Benoit Pierre - provided patches for compilation without IPC support, without HAVE_STRUCT_STAT_ST_BLKSIZE, and on MacOS
|
||||
* [gustav-b](https://codeberg.org/gustav-b) - suggested percentage formatting correction ([#80](https://codeberg.org/a-j-wood/pv/issues/80))
|
||||
* [Thomas Bertels](https://codeberg.org/tbertels) - updated French translations ([#83](https://codeberg.org/a-j-wood/pv/pulls/83))
|
||||
* [kevinruddy](https://codeberg.org/kevinruddy) - added decimal units option ([#85](https://codeberg.org/a-j-wood/pv/pulls/85))
|
||||
* [xmort](https://codeberg.org/xmort) - added **--output** option ([#90](https://codeberg.org/a-j-wood/pv/pulls/90))
|
||||
* [bogiord](https://codeberg.org/bogiord) - reported the loss of output block device size detection in 1.8.10, and suggested the fix ([#91](https://codeberg.org/a-j-wood/pv/issues/91))
|
||||
* [eborisch](https://codeberg.org/eborisch) - provided fix for misbehaviour when used with "`zfs send`" due to treating zero sized writes (generally due to timer interruption) as end of file ([#92](https://codeberg.org/a-j-wood/pv/pulls/92), [#93](https://codeberg.org/a-j-wood/pv/pulls/93))
|
||||
* [alexanderperlis](https://codeberg.org/alexanderperlis) - provided initial support for block devices with **--size `@`FILE** ([#94](https://codeberg.org/a-j-wood/pv/pulls/94))
|
||||
* [jettero](https://codeberg.org/jettero) - reported double-free coredump when using **--watchfd** after 1.8.10 ([#96](https://codeberg.org/a-j-wood/pv/issues/96))
|
||||
* Venky.N.Iyer - suggested **--stats** ([#49](https://codeberg.org/a-j-wood/pv/issues/49))
|
||||
* Roland Kletzing - suggested **--rate** with **--numeric** ([#17](https://codeberg.org/a-j-wood/pv/issues/17))
|
||||
* [Michael Mior](https://codeberg.org/michaelmior) - suggested **--store-and-forward** ([#100](https://codeberg.org/a-j-wood/pv/issues/100))
|
||||
* [dbungert](https://codeberg.org/dbungert) - reported issue with *valgrind* 3.23 misreporting leaking file descriptors ([#97](https://codeberg.org/a-j-wood/pv/issues/97))
|
||||
* Joachim Haga - suggested showing progress in the window title ([#3](https://codeberg.org/a-j-wood/pv/issues/3))
|
||||
* [Martin Sarsale](https://github.com/runa) - suggested showing progress in the process title ([#4](https://codeberg.org/a-j-wood/pv/issues/4))
|
||||
* [2bits](https://github.com/2bits) - reported position sensing fault with **--watchfd** in 1.9.0 ([#118](https://codeberg.org/a-j-wood/pv/issues/118))
|
||||
|
||||
Translations provided through [Codeberg Weblate](https://translate.codeberg.org/projects/pv/):
|
||||
|
||||
* **Czech**
|
||||
* [mmatous](https://translate.codeberg.org/user/mmatous/) (135)
|
||||
* **French**
|
||||
* anonymous suggestions (7)
|
||||
* **German**
|
||||
* [Hartmut Goebel](https://translate.codeberg.org/user/htgoebel/) (77)
|
||||
* [Benny](https://translate.codeberg.org/user/Benny/) (6)
|
||||
* [kre](https://translate.codeberg.org/user/kre/) (2)
|
||||
* [fnetX](https://translate.codeberg.org/user/fnetX/) (1)
|
||||
* **Polish**
|
||||
* [coralpink](https://translate.codeberg.org/user/coralpink/) (100)
|
||||
* **Russian**
|
||||
* [0ko](https://translate.codeberg.org/user/0ko/) (151)
|
||||
* **Turkish**
|
||||
* [omerdduran](https://translate.codeberg.org/user/omerdduran/) (129)
|
||||
|
||||
---
|
||||
|
||||
+47
-11
@@ -55,6 +55,15 @@ altered in future.
|
||||
|
||||
## Translation notes
|
||||
|
||||
Translators can use the Weblate instance hosted by Codeberg:
|
||||
[https://translate.codeberg.org/projects/pv/](https://translate.codeberg.org/projects/pv/)
|
||||
|
||||
If you don't see your language listed, raise an issue on the issue tracker
|
||||
(or just email the maintainer) asking for it to be added.
|
||||
|
||||
Alternatively, read on for details of how to maintain the translations
|
||||
directly within the source tree.
|
||||
|
||||
The message catalogues used to translate program messages into other
|
||||
languages are in the "`po/`" directory, named "`xx.po`", where "`xx`"
|
||||
is the ISO 639-1 2-letter language code, such as "`fr`" for French.
|
||||
@@ -73,21 +82,40 @@ It is the "`msgstr`" lines which need to be updated by translators.
|
||||
|
||||
Message catalogue files should all be encoded as UTF-8.
|
||||
|
||||
_FIXME: The test below doesn't work on Debian with only en_GB installed, and
|
||||
also it looks like the compiled-in LOCALEDIR is overriding LOCPATH._
|
||||
|
||||
After making a change to a "`.po`" file, test it by compiling it and installing
|
||||
to a temporary location, like this:
|
||||
|
||||
make install DESTDIR=/tmp/yourtest
|
||||
localedef -f UTF-8 -i de_DE /tmp/yourtest/usr/local/share/locale/de_DE.UTF-8
|
||||
LOCPATH=/tmp/yourtest/usr/local/share/locale \
|
||||
LC_ALL=de_DE.UTF-8 ./pv --help
|
||||
./configure --enable-debugging --prefix=/tmp/yourtest
|
||||
make clean
|
||||
make install
|
||||
localedef -f UTF-8 -i de_DE /tmp/yourtest/share/locale/de_DE.UTF-8
|
||||
bash
|
||||
export LOCPATH=/tmp/yourtest/share/locale
|
||||
export LC_ALL=de_DE.UTF-8
|
||||
export LANGUAGE=de_DE
|
||||
/tmp/yourtest/bin/pv --help
|
||||
exit
|
||||
|
||||
Replace "`--help`" with whatever is appropriate for your test. In this
|
||||
example, the language being tested is "`de`" (German), on a system which is
|
||||
running with UTF-8 support.
|
||||
|
||||
In the example above, a new shell is started by typing "`bash`" so that
|
||||
after your tests, "`exit`" will return you to your previous shell with your
|
||||
language settings intact.
|
||||
|
||||
Note that at the start, you have to re-run "`configure`" with "`--prefix`"
|
||||
rather than using "`make DESTDIR=...`", because the locale directory is set
|
||||
at compile time. Also, on Debian at least, both "`LC_ALL`" and "`LANGUAGE`"
|
||||
must be set.
|
||||
|
||||
To find untranslated strings in a language that's already supported but
|
||||
which you can help with gaps in, use this command:
|
||||
|
||||
msgattrib --untranslated < po/fr.po
|
||||
|
||||
replacing "`po/fr.po`" as appropriate.
|
||||
|
||||
To add a new language, create the new message catalogue file under "`po/`"
|
||||
by copying "`po/pv.pot`" to "`po/xx.po`", where "`xx`" is the language code,
|
||||
and adjusting it. The "`.pot`" file is generated automatically by "`make`".
|
||||
@@ -109,16 +137,24 @@ these will need to be corrected by translators.
|
||||
|
||||
The package maintainer should run through these steps for a new release:
|
||||
|
||||
* Check for patches and bug reports at https://tracker.debian.org/pkg/pv
|
||||
* Check for patches and bug reports:
|
||||
* <https://codeberg.org/a-j-wood/pv/issues>
|
||||
* <https://tracker.debian.org/pkg/pv>
|
||||
* <https://launchpad.net/ubuntu/+source/pv>
|
||||
* <https://archlinux.org/packages/extra/x86_64/pv/>
|
||||
* <https://packages.gentoo.org/packages/sys-apps/pv>
|
||||
* <https://cvsweb.openbsd.org/ports/sysutils/pv/>
|
||||
* <https://packages.fedoraproject.org/pkgs/pv/pv/>
|
||||
* Run "`make indent; make indent indentclean check`"
|
||||
* Check that `po/POTFILES.in` is up to date
|
||||
* Run "`make -C po update-po`"
|
||||
* Run "`make analyse`" and see whether remaining warnings can be addressed
|
||||
* Version bump and documentation checks:
|
||||
* Update the version in `configure.ac` and `docs/NEWS.md`
|
||||
* Check that `docs/NEWS.md` is up to date
|
||||
* Check that `docs/TODO.md` is up to date
|
||||
* Check that the manual `docs/pv.1` is up to date
|
||||
* Run "`make docs/pv.1.md`" and, if using VPATH, copy the result to the source directory
|
||||
* Check that the year displayed by src/main/version.c is correct
|
||||
* Ensure everything has been committed to the repository
|
||||
* Run "`autoreconf`" in the source directory
|
||||
* Consistency and build checks:
|
||||
@@ -128,8 +164,8 @@ The package maintainer should run through these steps for a new release:
|
||||
* Run "`make release MAINTAINER=<signing-user>`"
|
||||
* Update the project web site:
|
||||
* Copy the release `.tar.gz`, `.txt`, and `.asc` files to the web site
|
||||
* Use "`pandoc --from markdown --to html`" to convert the TODO, news, and manual to HTML
|
||||
* Update the TODO, news, and manual on the web site
|
||||
* Use "`pandoc --from markdown --to html`" to convert the news and manual to HTML
|
||||
* Update the news and manual on the web site
|
||||
* Update the version numbers on the web site
|
||||
* Update the package index on the web site
|
||||
* Create a new release in the repository, and apply the associated tag
|
||||
|
||||
+197
-137
@@ -1,52 +1,112 @@
|
||||
### 1.9.7 - 2 December 2024
|
||||
|
||||
* *feature:* new **--extra-display** option to update window and process titles ([#3](https://codeberg.org/a-j-wood/pv/issues/3), [#4](https://codeberg.org/a-j-wood/pv/issues/4))
|
||||
* *fix:* correct failure to report file positions in **--watchfd** ([#118](https://codeberg.org/a-j-wood/pv/issues/118))
|
||||
* *i18n:* Russian translations added
|
||||
* *cleanup:* tests added for **--watchfd** ([#10](https://codeberg.org/a-j-wood/pv/issues/10))
|
||||
* *cleanup:* worked around file descriptor leak false positives in valgrind 3.23 ([#97](https://codeberg.org/a-j-wood/pv/issues/97))
|
||||
* *cleanup:* cleared all *shellcheck* warnings in the test scripts
|
||||
* *cleanup:* check at compile-time whether **--remote** is going to be usable ([#119](https://codeberg.org/a-j-wood/pv/issues/119))
|
||||
|
||||
### 1.9.0 - 15 October 2024
|
||||
|
||||
* *feature:* new **--store-and-forward** option to read input to a file first, then write it to the output ([#100](https://codeberg.org/a-j-wood/pv/issues/100))
|
||||
* *feature:* new **--stats** option to show transfer stats at the end, like "`ping`" ([#49](https://codeberg.org/a-j-wood/pv/issues/49))
|
||||
* *feature:* **--rate** can now be used with **--numeric** ([#17](https://codeberg.org/a-j-wood/pv/issues/17))
|
||||
* *feature:* **--gauge** with **--progress** to show rate gauge when size is unknown ([#46](https://codeberg.org/a-j-wood/pv/issues/46))
|
||||
* *i18n:* comprehensive German translations update
|
||||
* *i18n:* comprehensive Polish translations update
|
||||
* *i18n:* complete Turkish translations added
|
||||
* *i18n:* complete Czech translations added
|
||||
* *i18n:* updates to French translations
|
||||
* *fix:* resume stopped pipelines when running in the background (part of [#56](https://codeberg.org/a-j-wood/pv/issues/56))
|
||||
* *fix:* inspect the output pipe buffer to give a more accurate progress indicator of how much the next command has consumed
|
||||
* *fix:* prefix completion time (**--fineta**) with *FIN* rather than *ETA* ([#43](https://codeberg.org/a-j-wood/pv/issues/43))
|
||||
* *fix:* surround average rate (**--average-rate**) with brackets rather than square brackets
|
||||
* *fix:* correct a memory leak in **--watchfd PID**
|
||||
* *fix:* make **--direct-io** work correctly with **--output** instead of assuming stdout
|
||||
* *fix:* call `posix_fadvise()` on every input, not just the first one
|
||||
* *fix:* write UTC timestamps in debugging mode to avoid lockups in signal handlers
|
||||
* *security:* added a signed *MANIFEST* file to releases
|
||||
* *cleanup:* removed TODO.md, since it's just an outdated copy of the issue tracker
|
||||
* *cleanup:* re-ordered structure members to reduce padding
|
||||
* *cleanup:* improved readability of *SIGTTOU* handling code
|
||||
* *cleanup:* refactored to separate display, transfer, and calculation more cleanly
|
||||
* *cleanup:* instead of moving stderr when backgrounded, set a suspend-output flag
|
||||
|
||||
### 1.8.14 - 7 September 2024
|
||||
|
||||
* *fix:* correct double-free on exit when using **--watchfd** ([#96](https://codeberg.org/a-j-wood/pv/issues/96)) reported by [jettero](https://codeberg.org/jettero)
|
||||
|
||||
### 1.8.13 - 18 August 2024
|
||||
|
||||
* *feature:* when using **--size @FILE**, *FILE* can be a block device, and its size will be used (pull request [#94](https://codeberg.org/a-j-wood/pv/pulls/94)) supplied by [alexanderperlis](https://codeberg.org/alexanderperlis)
|
||||
|
||||
### 1.8.12 - 18 July 2024
|
||||
|
||||
* *fix:* correct the detection of output block device size that was broken in 1.8.10 ([#91](https://codeberg.org/a-j-wood/pv/issues/91))
|
||||
* *fix:* do not treat a zero/interrupted write as an end of file (pull requests [#92](https://codeberg.org/a-j-wood/pv/pulls/92) and [#93](https://codeberg.org/a-j-wood/pv/pulls/93))
|
||||
|
||||
### 1.8.10 - 15 June 2024
|
||||
|
||||
* *feature:* new **--output** option to write to a file instead of standard output (pull request [#90](https://codeberg.org/a-j-wood/pv/pulls/90)) supplied by [xmort](https://codeberg.org/xmort)
|
||||
|
||||
### 1.8.9 - 21 April 2024
|
||||
|
||||
* *feature:* new **--si** option to display and interpret size suffixes in multiples of 1000 rather than 1024 (pull request [#85](https://codeberg.org/a-j-wood/pv/pulls/85)) supplied by [kevinruddy](https://codeberg.org/kevinruddy)
|
||||
* *fix:* continue producing progress output when the output is blocking writes ([#34](https://codeberg.org/a-j-wood/pv/issues/34), [#86](https://codeberg.org/a-j-wood/pv/issues/86), [#87](https://codeberg.org/a-j-wood/pv/issues/87))
|
||||
* *fix:* honour the *TMPDIR* / *TMP* environment variables again, rather than hard-coding "`/tmp`", when using a terminal lock file (originally removed in 1.8.0) ([#88](https://codeberg.org/a-j-wood/pv/issues/88))
|
||||
* *i18n:* corrections and missing strings added to French translations (pull request [#83](https://codeberg.org/a-j-wood/pv/pulls/83)) supplied by [Thomas Bertels](https://codeberg.org/tbertels)
|
||||
|
||||
### 1.8.5 - 19 November 2023
|
||||
|
||||
* fix: corrected percentage formatting so it doesn't jump from 2 to 3 characters wide at 100% ([#80](https://codeberg.org/a-j-wood/pv/issues/80))
|
||||
* fix: replaced "`--remote`" mechanism, using a temporary file instead of SysV IPC, so it can work reliably even when there are multiple PV instances
|
||||
* fix: corrected compilation failure when without IPC support
|
||||
* security: addressed all issues highlighted by the software auditing tools "`splint`" and "`flawfinder`" (see "`make analyse`") ([#77](https://codeberg.org/a-j-wood/pv/issues/77))
|
||||
* cleanup: compilation warnings fixed on non-IPC and MacOS systems
|
||||
* *fix:* corrected percentage formatting so it doesn't jump from 2 to 3 characters wide at 100% ([#80](https://codeberg.org/a-j-wood/pv/issues/80))
|
||||
* *fix:* replaced **--remote** mechanism, using a temporary file instead of SysV IPC, so it can work reliably even when there are multiple PV instances
|
||||
* *fix:* corrected compilation failure when without IPC support
|
||||
* *security:* addressed all issues highlighted by the software auditing tools "`splint`" and "`flawfinder`" (see "`make analyse`") ([#77](https://codeberg.org/a-j-wood/pv/issues/77))
|
||||
* *cleanup:* compilation warnings fixed on non-IPC and MacOS systems
|
||||
|
||||
### 1.8.0 - 24 September 2023
|
||||
|
||||
#### Features
|
||||
|
||||
* feature: new "`--discard`" option to discard input as if writing to */dev/null* ([#42](https://codeberg.org/a-j-wood/pv/issues/42))
|
||||
* feature: new "`--error-skip-block`" option to make "`--skip-errors`" skip whole blocks ([#37](https://codeberg.org/a-j-wood/pv/issues/37))
|
||||
* feature: use `posix_fadvise()` like `cat`(1) does, to improve efficiency ([#39](https://codeberg.org/a-j-wood/pv/issues/39))
|
||||
* feature: new "`--enable-static`" option to "`configure`" for static builds ([#75](https://codeberg.org/a-j-wood/pv/pull/75))
|
||||
* *feature:* new **--discard** option to discard input as if writing to */dev/null* ([#42](https://codeberg.org/a-j-wood/pv/issues/42))
|
||||
* *feature:* new **--error-skip-block** option to make **--skip-errors** skip whole blocks ([#37](https://codeberg.org/a-j-wood/pv/issues/37))
|
||||
* *feature:* use `posix_fadvise()` like `cat`(1) does, to improve efficiency ([#39](https://codeberg.org/a-j-wood/pv/issues/39))
|
||||
* *feature:* new **--enable-static** option to "`configure`" for static builds ([#75](https://codeberg.org/a-j-wood/pv/pull/75))
|
||||
|
||||
#### Security
|
||||
|
||||
* security: with "`--pidfile`", write to a temporary file and rename it into place, to improve security
|
||||
* security: keep self-contained copies of name and format string in PV internal state for memory safety
|
||||
* security: ignore _TMP_ / _TMPDIR_ environment variables when using a terminal lock file
|
||||
* *security:* with **--pidfile**, write to a temporary file and rename it into place, to improve security
|
||||
* *security:* keep self-contained copies of name and format string in PV internal state for memory safety
|
||||
* *security:* ignore *TMP* / *TMPDIR* environment variables when using a terminal lock file
|
||||
|
||||
#### Fixes
|
||||
|
||||
* fix: only report errors about missing files when starting to transfer from them, not while calculating size, and behave more like `cat`(1) by skipping them and moving on
|
||||
* fix: auto-calculate total line count with "`--line-mode`" when all inputs are regular files
|
||||
* fix: use `clock_gettime()` in ETA calculation to cope with machine suspend/resume ([#13](https://codeberg.org/a-j-wood/pv/issues/13))
|
||||
* fix: if "`--width`" or "`--height`" were provided, do not change them when the window size changes ([#36](https://codeberg.org/a-j-wood/pv/issues/36))
|
||||
* fix: when a file descriptor position in "`--watchfd`" moves backwards, show the rate using the correct prefix ([#41](https://codeberg.org/a-j-wood/pv/issues/41))
|
||||
* fix: rewrite terminal state save/restore so state is not intermittently garbled on exit when using "`--cursor`" ([#20](https://codeberg.org/a-j-wood/pv/issues/20)), ([#24](https://codeberg.org/a-j-wood/pv/issues/24))
|
||||
* *fix:* only report errors about missing files when starting to transfer from them, not while calculating size, and behave more like `cat`(1) by skipping them and moving on
|
||||
* *fix:* auto-calculate total line count with **--line-mode** when all inputs are regular files
|
||||
* *fix:* use `clock_gettime()` in ETA calculation to cope with machine suspend/resume ([#13](https://codeberg.org/a-j-wood/pv/issues/13))
|
||||
* *fix:* if **--width** or **--height** were provided, do not change them when the window size changes ([#36](https://codeberg.org/a-j-wood/pv/issues/36))
|
||||
* *fix:* when a file descriptor position in **--watchfd** moves backwards, show the rate using the correct prefix ([#41](https://codeberg.org/a-j-wood/pv/issues/41))
|
||||
* *fix:* rewrite terminal state save/restore so state is not intermittently garbled on exit when using **--cursor** ([#20](https://codeberg.org/a-j-wood/pv/issues/20)), ([#24](https://codeberg.org/a-j-wood/pv/issues/24))
|
||||
|
||||
#### Cleanups
|
||||
|
||||
* cleanup: addressed many potential issues highlighted by the software auditing tools "`splint`" and "`flawfinder`" (see new target "`make analyse`")
|
||||
* cleanup: switched the build system to GNU Automake
|
||||
* cleanup: replaced the test harness with the one native to GNU Automake
|
||||
* cleanup: added a test for terminal width detection to "`make check`"
|
||||
* cleanup: added a test to "`make check`" to ensure that "`make install`" installs everything expected
|
||||
* cleanup: replaced *AC_HEADER_TIOCGWINSZ* with *AC_CHECK_HEADERS(sys/ioctl.h)* for better MacOS compatibility ([#74](https://codeberg.org/a-j-wood/pv/issues/74))
|
||||
* cleanup: with "`--sync`", call `fsync()` instead of `fdatasync()` on incapable systems ([#73](https://codeberg.org/a-j-wood/pv/issues/73))
|
||||
* cleanup: the manual is now a static file instead of needing to be built with "`configure`"
|
||||
* *cleanup:* addressed many potential issues highlighted by the software auditing tools "`splint`" and "`flawfinder`" (see new target "`make analyse`")
|
||||
* *cleanup:* switched the build system to GNU Automake
|
||||
* *cleanup:* replaced the test harness with the one native to GNU Automake
|
||||
* *cleanup:* added a test for terminal width detection to "`make check`"
|
||||
* *cleanup:* added a test to "`make check`" to ensure that "`make install`" installs everything expected
|
||||
* *cleanup:* replaced *AC_HEADER_TIOCGWINSZ* with *AC_CHECK_HEADERS(sys/ioctl.h)* for better MacOS compatibility ([#74](https://codeberg.org/a-j-wood/pv/issues/74))
|
||||
* *cleanup:* with **--sync**, call `fsync()` instead of `fdatasync()` on incapable systems ([#73](https://codeberg.org/a-j-wood/pv/issues/73))
|
||||
* *cleanup:* the manual is now a static file instead of needing to be built with "`configure`"
|
||||
|
||||
#### Dropped items
|
||||
|
||||
* dropped: dropped support for "`--enable-static-nls`"
|
||||
* dropped: removed the Linux Software Map file, as the LSM project appears to be long dead
|
||||
* dropped: will no longer publish to SourceForge as it has a chequered history and is unnecessary
|
||||
* dropped: removed project from GitHub and moved to Codeberg - see "[Give Up GitHub](https://giveupgithub.org/)"
|
||||
* *dropped:* dropped support for **--enable-static-nls**
|
||||
* *dropped:* removed the Linux Software Map file, as the LSM project appears to be long dead
|
||||
* *dropped:* will no longer publish to SourceForge as it has a chequered history and is unnecessary
|
||||
* *dropped:* removed project from GitHub and moved to Codeberg - see "[Give Up GitHub](https://giveupgithub.org/)"
|
||||
|
||||
#### Other items
|
||||
|
||||
@@ -54,89 +114,89 @@
|
||||
|
||||
### 1.7.24 - 30 July 2023
|
||||
|
||||
* fix: correct terminal size detection, broken in 1.7.17 by the configuration script rewrite ([#72](https://codeberg.org/a-j-wood/pv/issues/72))
|
||||
* security: removed *DEBUG* environment variable in debug mode, added "`--debug`" instead
|
||||
* cleanup: added "`make analyse`" to run "`splint`" and "`flawfinder`" on all source files
|
||||
* cleanup: corrected detection of boolean capability
|
||||
* cleanup: word wrapping of "`--help`" output is now multi-byte locale aware
|
||||
* cleanup: adjusted "`indent`" rules to line length of 120 and reformatted code
|
||||
* *fix:* correct terminal size detection, broken in 1.7.17 by the configuration script rewrite ([#72](https://codeberg.org/a-j-wood/pv/issues/72))
|
||||
* *security:* removed *DEBUG* environment variable in debug mode, added **--debug** instead
|
||||
* *cleanup:* added "`make analyse`" to run "`splint`" and "`flawfinder`" on all source files
|
||||
* *cleanup:* corrected detection of boolean capability
|
||||
* *cleanup:* word wrapping of **--help** output is now multi-byte locale aware
|
||||
* *cleanup:* adjusted "`indent`" rules to line length of 120 and reformatted code
|
||||
|
||||
### 1.7.18 - 28 July 2023
|
||||
### 1.7.18 - 28 July 2023
|
||||
|
||||
* fix: language file installation had been broken by the configuration script rewrite
|
||||
* *fix:* language file installation had been broken by the configuration script rewrite
|
||||
|
||||
### 1.7.17 - 27 July 2023
|
||||
|
||||
* feature: new "`--sync`" option to flush cache to disk after every write (related to [#6](https://codeberg.org/a-j-wood/pv/issues/6), to improve accuracy when writing to slow disks)
|
||||
* feature: new "`--direct-io`" option to bypass cache - implements [#29 "Option to enable *O_DIRECT*"](https://codeberg.org/a-j-wood/pv/issues/29) - requested by Romain Kang, Jacek Wielemborek
|
||||
* fix: correct byte prefix size to 2 spaces in rate display, so progress display size remains constant at low transfer rates
|
||||
* cleanup: rewrote `configure.in` as per suggestions in newer "`autoconf`" manuals
|
||||
* cleanup: replaced `header.in` with one generated by "`autoheader`", moving custom logic to a separate header file "`config-aux.h`"
|
||||
* cleanup: added copyright notice to all source files as per GNU standards
|
||||
* cleanup: changed "`--version`" output to conform to GNU standards
|
||||
* cleanup: replaced backticks with `$()` in all shell scripts that did not come from elsewhere, as backticks are deprecated and harder to read
|
||||
* cleanup: improved the output formatting of "`make test`"
|
||||
* cleanup: extended the "`make test`" mechanism to allow certain tests to be skipped on platforms that cannot support them
|
||||
* cleanup: skip the "pipe" test (for *SIGPIPE*) if GNU "`head`" is not available, so that "`make test`" on stock OpenBSD 7.3 works
|
||||
* cleanup: added a lot more tests to "`make test`"
|
||||
* cleanup: replace all calls to `sprintf()` and `snprintf()` with a new wrapper function `pv_snprintf()` to improve security and compatibility
|
||||
* cleanup: replace all calls to `strcat()` with a wrapper `pv_strlcat()` to improve security and compatibility
|
||||
* cleanup: replace all `write()` calls to the terminal with a wrapper `pv_write_retry()` for consistency
|
||||
* cleanup: tidy up and fix compilation warning in "`--watchfd`" code
|
||||
* cleanup: rewrote all local shell scripts to pass analysis by [ShellCheck](https://www.shellcheck.net)
|
||||
* *feature:* new **--sync** option to flush cache to disk after every write (related to [#6](https://codeberg.org/a-j-wood/pv/issues/6), to improve accuracy when writing to slow disks)
|
||||
* *feature:* new **--direct-io** option to bypass cache - implements [#29 "Option to enable O_DIRECT"](https://codeberg.org/a-j-wood/pv/issues/29) - requested by Romain Kang, Jacek Wielemborek
|
||||
* *fix:* correct byte prefix size to 2 spaces in rate display, so progress display size remains constant at low transfer rates
|
||||
* *cleanup:* rewrote `configure.in` as per suggestions in newer "`autoconf`" manuals
|
||||
* *cleanup:* replaced `header.in` with one generated by "`autoheader`", moving custom logic to a separate header file "`config-aux.h`"
|
||||
* *cleanup:* added copyright notice to all source files as per GNU standards
|
||||
* *cleanup:* changed **--version** output to conform to GNU standards
|
||||
* *cleanup:* replaced backticks with `$()` in all shell scripts that did not come from elsewhere, as backticks are deprecated and harder to read
|
||||
* *cleanup:* improved the output formatting of "`make test`"
|
||||
* *cleanup:* extended the "`make test`" mechanism to allow certain tests to be skipped on platforms that cannot support them
|
||||
* *cleanup:* skip the "pipe" test (for *SIGPIPE*) if GNU "`head`" is not available, so that "`make test`" on stock OpenBSD 7.3 works
|
||||
* *cleanup:* added a lot more tests to "`make test`"
|
||||
* *cleanup:* replace all calls to `sprintf()` and `snprintf()` with a new wrapper function `pv_snprintf()` to improve security and compatibility
|
||||
* *cleanup:* replace all calls to `strcat()` with a wrapper `pv_strlcat()` to improve security and compatibility
|
||||
* *cleanup:* replace all `write()` calls to the terminal with a wrapper `pv_write_retry()` for consistency
|
||||
* *cleanup:* tidy up and fix compilation warning in **--watchfd** code
|
||||
* *cleanup:* rewrote all local shell scripts to pass analysis by [ShellCheck](https://www.shellcheck.net)
|
||||
|
||||
### 1.7.0 - 17 July 2023
|
||||
|
||||
* dropped: support for Red Hat Enterprise Linux and its derivatives has been dropped; removed the RPM spec file, and will no longer build binaries
|
||||
* feature: the "`--size`" option now accepts "`@filename`" to use the size of another file (pull request [#57](https://codeberg.org/a-j-wood/pv/pull/57) supplied by [Dave Beckett](https://github.com/dajobe))
|
||||
* feature: the "`--watchfd`" option is now available on OS X (pull request [#60](https://codeberg.org/a-j-wood/pv/pull/60) supplied by [christoph-zededa](https://github.com/christoph-zededa))
|
||||
* feature: new "`--bits`" option to show bit count instead of byte count (adapted from pull request [#63](https://codeberg.org/a-j-wood/pv/pull/63) supplied by [Nick Black](https://nick-black.com))
|
||||
* feature: new "`--average-rate-window`" option, to set the window over which the average rate is calculated, also used for ETA (modified from pull request [#65](https://codeberg.org/a-j-wood/pv/pull/65) supplied by [lemonsqueeze](https://github.com/lemonsqueeze))
|
||||
* feature: the "`--watchfd`" option will now show relative filenames, if they are under the current directory (pull request [#66](https://codeberg.org/a-j-wood/pv/pull/66) supplied by [ikasty](https://github.com/ikasty))
|
||||
* fix: correction to `pv_in_foreground()` to behave as its comment block says it should, when not on a terminal - corrects [#19 "No output in Arch Linux initcpio after 1.6.6"](https://codeberg.org/a-j-wood/pv/issues/19), [#31 "No output written from inside zsh <() construct"](https://codeberg.org/a-j-wood/pv/issues/31), [#55 "pv Stopped Working in the Background"](https://codeberg.org/a-j-wood/pv/issues/55) (pull request [#64](https://codeberg.org/a-j-wood/pv/pull/64) supplied by [Michael Weiß](https://github.com/quitschbo))
|
||||
* fix: workaround for OS X 11 behaviour in configure script regarding stat64 at compile time (pull request [#57](https://codeberg.org/a-j-wood/pv/pull/57) supplied by [Dave Beckett](https://github.com/dajobe))
|
||||
* fix: workaround for macOS equivalence of stat to stat64 - patches from [Filippo Valsorda](https://github.com/FiloSottile) and [Demitri Muna](https://github.com/demitri), correcting [#33 "Fix compilation problems due to `stat64()` on Apple Silicon"](https://codeberg.org/a-j-wood/pv/issues/33)
|
||||
* fix: add burst rate limit to transfer, so rate limits are not broken by bursty traffic (pull request [#62](https://codeberg.org/a-j-wood/pv/pull/62) supplied by [Volodymyr Bychkovyak](https://github.com/vbychkoviak))
|
||||
* fix: corrected "`--force`" option so it will still output progress when not in the same process group as the owner of the terminal - corrects [#23 "No output with "`-f`" when run in background after 1.6.6"](https://codeberg.org/a-j-wood/pv/issues/23) and helps to correct [#31 "No output written from inside zsh <() construct"](https://codeberg.org/a-j-wood/pv/issues/31)
|
||||
* fix: corrected elapsed time display to show as D:HH:MM:SS after 1 day, like the ETA does - corrects [#16 "Show days in same format in ETA as in elapsed time"](https://codeberg.org/a-j-wood/pv/issues/16)
|
||||
* fix: corrected bug where percentages went down after 100% when in "`--numeric`" mode with a "`--size`" that was too small - corrects [#26 "Correct "`-n`" behaviour when going past 100% of "`-s`" size"](https://codeberg.org/a-j-wood/pv/issues/26)
|
||||
* i18n: recoded Polish translation file to UTF-8
|
||||
* i18n: removed inaccurate fuzzy translation matches
|
||||
* docs: moved all open issues into GitHub and updated the TODO list
|
||||
* docs: renamed README to README.md and altered it to Markdown format
|
||||
* docs: moved contributors from the README to docs/ACKNOWLEDGEMENTS.md
|
||||
* docs: moved TODO to TODO.md and altered it to Markdown format
|
||||
* docs: moved NEWS to NEWS.md, converted it to UTF-8, and altered it to Markdown format
|
||||
* *dropped:* support for Red Hat Enterprise Linux and its derivatives has been dropped; removed the RPM spec file, and will no longer build binaries
|
||||
* *feature:* the **--size** option now accepts "`@filename`" to use the size of another file (pull request [#57](https://codeberg.org/a-j-wood/pv/pull/57) supplied by [Dave Beckett](https://github.com/dajobe))
|
||||
* *feature:* the **--watchfd** option is now available on OS X (pull request [#60](https://codeberg.org/a-j-wood/pv/pull/60) supplied by [christoph-zededa](https://github.com/christoph-zededa))
|
||||
* *feature:* new **--bits** option to show bit count instead of byte count (adapted from pull request [#63](https://codeberg.org/a-j-wood/pv/pull/63) supplied by [Nick Black](https://nick-black.com))
|
||||
* *feature:* new **--average-rate-window** option, to set the window over which the average rate is calculated, also used for ETA (modified from pull request [#65](https://codeberg.org/a-j-wood/pv/pull/65) supplied by [lemonsqueeze](https://github.com/lemonsqueeze))
|
||||
* *feature:* the **--watchfd** option will now show relative filenames, if they are under the current directory (pull request [#66](https://codeberg.org/a-j-wood/pv/pull/66) supplied by [ikasty](https://github.com/ikasty))
|
||||
* *fix:* correction to `pv_in_foreground()` to behave as its comment block says it should, when not on a terminal - corrects [#19 "No output in Arch Linux initcpio after 1.6.6"](https://codeberg.org/a-j-wood/pv/issues/19), [#31 "No output written from inside zsh <() construct"](https://codeberg.org/a-j-wood/pv/issues/31), [#55 "pv Stopped Working in the Background"](https://codeberg.org/a-j-wood/pv/issues/55) (pull request [#64](https://codeberg.org/a-j-wood/pv/pull/64) supplied by [Michael Weiß](https://github.com/quitschbo))
|
||||
* *fix:* workaround for OS X 11 behaviour in configure script regarding stat64 at compile time (pull request [#57](https://codeberg.org/a-j-wood/pv/pull/57) supplied by [Dave Beckett](https://github.com/dajobe))
|
||||
* *fix:* workaround for macOS equivalence of stat to stat64 - patches from [Filippo Valsorda](https://github.com/FiloSottile) and [Demitri Muna](https://github.com/demitri), correcting [#33 "Fix compilation problems due to `stat64()` on Apple Silicon"](https://codeberg.org/a-j-wood/pv/issues/33)
|
||||
* *fix:* add burst rate limit to transfer, so rate limits are not broken by bursty traffic (pull request [#62](https://codeberg.org/a-j-wood/pv/pull/62) supplied by [Volodymyr Bychkovyak](https://github.com/vbychkoviak))
|
||||
* *fix:* corrected **--force** option so it will still output progress when not in the same process group as the owner of the terminal - corrects [#23 "No output with "-f" when run in background after 1.6.6"](https://codeberg.org/a-j-wood/pv/issues/23) and helps to correct [#31 "No output written from inside zsh <() construct"](https://codeberg.org/a-j-wood/pv/issues/31)
|
||||
* *fix:* corrected elapsed time display to show as D:HH:MM:SS after 1 day, like the ETA does - corrects [#16 "Show days in same format in ETA as in elapsed time"](https://codeberg.org/a-j-wood/pv/issues/16)
|
||||
* *fix:* corrected bug where percentages went down after 100% when in **--numeric** mode with a **--size** that was too small - corrects [#26 "Correct "-n" behaviour when going past 100% of "-s" size"](https://codeberg.org/a-j-wood/pv/issues/26)
|
||||
* *i18n:* recoded Polish translation file to UTF-8
|
||||
* *i18n:* removed inaccurate fuzzy translation matches
|
||||
* *docs:* moved all open issues into GitHub and updated the TODO list
|
||||
* *docs:* renamed README to README.md and altered it to Markdown format
|
||||
* *docs:* moved contributors from the README to docs/ACKNOWLEDGEMENTS.md
|
||||
* *docs:* moved TODO to TODO.md and altered it to Markdown format
|
||||
* *docs:* moved NEWS to NEWS.md, converted it to UTF-8, and altered it to Markdown format
|
||||
|
||||
### 1.6.20 - 12 September 2021
|
||||
|
||||
* fix: add missing `stddef.h` include to `number.c` (Sam James)
|
||||
* *fix:* add missing `stddef.h` include to `number.c` (Sam James)
|
||||
|
||||
### 1.6.19 - 5 September 2021
|
||||
|
||||
* fix: starting pv in the background no longer immediately stops unless the transfer is to/from the terminal (Andriy Gapon, Jonathan Elchison)
|
||||
* fix: using "`-B`", "`-A`", or "`-T`" now switches on "`-C`" implicitly (Johannes Gerer, André Stapf)
|
||||
* fix: AIX build fixes (Peter Korsgaard)
|
||||
* i18n: updated German "`--help`" translations (Richard Fonfara)
|
||||
* i18n: switched to UTF-8 encoding, added missing translations (de,fr,pt)
|
||||
* docs: new "common switches" manual section (Jacek Wielemborek)
|
||||
* docs: use placeholder instead of `/dev/sda` in the manual (Pranav Peshwe)
|
||||
* docs: mention MacOS pipes and "`-B 1024`" in the manual (Jan Venekamp)
|
||||
* docs: correct shell in `autoconf/scripts/index.sh` (Juan Picca)
|
||||
* cleanup: various compiler warnings cleaned up
|
||||
* *fix:* starting pv in the background no longer immediately stops unless the transfer is to/from the terminal (Andriy Gapon, Jonathan Elchison)
|
||||
* *fix:* using **-B**, **-A**, or **-T** now switches on **-C** implicitly (Johannes Gerer, André Stapf)
|
||||
* *fix:* AIX build fixes (Peter Korsgaard)
|
||||
* *i18n:* updated German **--help** translations (Richard Fonfara)
|
||||
* *i18n:* switched to UTF-8 encoding, added missing translations (de,fr,pt)
|
||||
* *docs:* new "common switches" manual section (Jacek Wielemborek)
|
||||
* *docs:* use placeholder instead of `/dev/sda` in the manual (Pranav Peshwe)
|
||||
* *docs:* mention MacOS pipes and **-B 1024** in the manual (Jan Venekamp)
|
||||
* *docs:* correct shell in `autoconf/scripts/index.sh` (Juan Picca)
|
||||
* *cleanup:* various compiler warnings cleaned up
|
||||
|
||||
Full changelog is below:
|
||||
|
||||
* (r181) added common switches section to manual (Jacek Wielemborek)
|
||||
* (r184) use placeholder instead of /dev/sda in the manual (Pranav Peshwe)
|
||||
* (r185) replace ash with sh in autoconf/scripts/index.sh (Juan Picca)
|
||||
* (r185) added note to manual about "`-B 1024`" in MacOS pipes (Jan Venekamp)
|
||||
* (r185) added note to manual about **-B 1024** in MacOS pipes (Jan Venekamp)
|
||||
* (r185) fix AIX config check when the CWD contains "yes" (Peter Korsgaard)
|
||||
* (r189) (#1556) updated German "`--help`" translations (Richard Fonfara)
|
||||
* (r189) (#1556) updated German **--help** translations (Richard Fonfara)
|
||||
* (r189) updated missing German translations and changed to UTF-8 encoding
|
||||
* (r191) updated missing French translations and changed to UTF-8 encoding
|
||||
* (r193) updated missing Portuguese translations, changed to UTF-8 encoding
|
||||
* (r196) (#1563) using "`-B`", "`-A`", or "`-T`" now switches on "`-C`" implicitly (Johannes Gerer, André Stapf)
|
||||
* (r196) (#1563) using **-B**, **-A**, or **-T** now switches on **-C** implicitly (Johannes Gerer, André Stapf)
|
||||
* (r199) fixed numerous compiler warnings in newer GCC versions
|
||||
* (r200,205) fixed bug where "`pv /dev/zero >/dev/null &`" stopped immediately (Jonathan Elchison, Andriy Gapon)
|
||||
* (r203,205) marked unused arguments with GCC unused attribute, started using boolean data type for flags, corrected more compiler warnings
|
||||
@@ -144,22 +204,22 @@ Full changelog is below:
|
||||
### 1.6.6 - 30 June 2017
|
||||
|
||||
* (r161) use `%llu` instead of `%Lu` for better compatibility (Eric A. Borisch)
|
||||
* (r162) (#1532) fix target buffer size ("`-B`") being ignored (AndCycle, Ilya Basin, Antoine Beaupré)
|
||||
* (r162) (#1532) fix target buffer size (**-B**) being ignored (AndCycle, Ilya Basin, Antoine Beaupré)
|
||||
* (r164) cap read/write sizes, and check elapsed time during read/write cycles, to avoid display hangs with large buffers or slow media; also remove `select()` call from repeated_write function as it slows the transfer down and the wrapping `alarm()` means it is unnecessary
|
||||
* (r169) (#1477) use alternate form for transfer counter, such that 13GB is shown as 13.0GB so it's the same width as 13.1GB (André Stapf)
|
||||
* (r171) cleanup: units corrections in man page, of the form kb -> KiB
|
||||
* (r175) report error in "`-d`" if process fd directory is unreadable, or if process disappears before we start the main loop (Jacek Wielemborek)
|
||||
* (r175) report error in **-d** if process fd directory is unreadable, or if process disappears before we start the main loop (Jacek Wielemborek)
|
||||
|
||||
### 1.6.0 - 15 March 2015
|
||||
|
||||
* fix lstat64 support when unavailable - separate patches supplied by Ganael Laplanche and Peter Korsgaard
|
||||
* (#1506) new option "`-D`" / "`--delay-start`" to only show bar after N seconds (Damon Harper)
|
||||
* new option "`--fineta`" / "`-I`" to show ETA as time of day rather than time remaining - patch supplied by Erkki Seppälä (r147)
|
||||
* (#1509) change ETA ("`--eta`" / "`-e`") so that days are given if the hours remaining are 24 or more (Jacek Wielemborek)
|
||||
* (#1506) new option **-D** / **--delay-start** to only show bar after N seconds (Damon Harper)
|
||||
* new option **--fineta** / **-I** to show ETA as time of day rather than time remaining - patch supplied by Erkki Seppälä (r147)
|
||||
* (#1509) change ETA (**--eta** / **-e**) so that days are given if the hours remaining are 24 or more (Jacek Wielemborek)
|
||||
* (#1499) repeat read and write attempts on partial buffer fill/empty to work around post-signal transfer rate drop reported by Ralf Ramsauer
|
||||
* (#1507) do not try to calculate total size in line mode, due to bug reported by Jacek Wielemborek and Michiel Van Herwegen
|
||||
* cleanup: removed defunct RATS comments and unnecessary copyright notices
|
||||
* clean up displayed lines when using "`--watchfd PID`", when PID exits
|
||||
* clean up displayed lines when using **--watchfd PID**, when PID exits
|
||||
* output errors on a new line to avoid overwriting transfer bar
|
||||
|
||||
### 1.5.7 - 26 August 2014
|
||||
@@ -175,25 +235,25 @@ Full changelog is below:
|
||||
|
||||
### 1.5.2 - 10 February 2014
|
||||
|
||||
* allow "`--watchfd`" to look at block devices
|
||||
* let "`--watchfd PID:FD`" work with "`--size N`"
|
||||
* allow **--watchfd** to look at block devices
|
||||
* let **--watchfd PID:FD** work with **--size N**
|
||||
* moved contributors out of the manual as the list was too long (NB everyone is still listed in the README and always will be)
|
||||
|
||||
### 1.5.1 - 23 January 2014
|
||||
|
||||
* new option "`--watchfd`" - suggested by Jacek Wielemborek and "fdwatch"
|
||||
* new option **--watchfd** - suggested by Jacek Wielemborek and "fdwatch"
|
||||
* use non-block flag with `splice()`
|
||||
* new display option "`--buffer-percent`", suggested by Kim Krecht
|
||||
* new display option "`--last-written`", suggested by Kim Krecht
|
||||
* new transfer option "`--no-splice`"
|
||||
* new display option **--buffer-percent**, suggested by Kim Krecht
|
||||
* new display option **--last-written**, suggested by Kim Krecht
|
||||
* new transfer option **--no-splice**
|
||||
* fix for minor bug which dropped display elements after one empty one
|
||||
* fix for single fd leak on exit (Cristian Ciupitu)
|
||||
|
||||
### 1.4.12 - 5 August 2013
|
||||
|
||||
* new option "`--null`" - patch supplied by Zing Shishak
|
||||
* new option **--null** - patch supplied by Zing Shishak
|
||||
* AIX build fix (add "`-lc128`") - with help from Pawel Piatek
|
||||
* AIX "`-c`" fixes - with help from Pawel Piatek
|
||||
* AIX **-c** fixes - with help from Pawel Piatek
|
||||
* SCO build fix (`po2table.sh`) - reported by Wouter Pronk
|
||||
* test scripts fix for older distributions - patch from Bryan Dongray
|
||||
* fix for `splice()` not using stdin - patch from Zev Weiss
|
||||
@@ -204,41 +264,41 @@ Full changelog is below:
|
||||
|
||||
### 1.4.5 - 10 January 2013
|
||||
|
||||
* updated manual page to show known problem with "`-R`" on Cygwin
|
||||
* updated manual page to show known problem with **-R** on Cygwin
|
||||
|
||||
### 1.4.4 - 11 December 2012
|
||||
|
||||
* added debugging, see "`pv -h`" when `configure` is run with "`--enable-debugging`"
|
||||
* added debugging, see "`pv -h`" when `configure` is run with **--enable-debugging**
|
||||
* rewrote cursor positioning code used when IPC is unavailable (Cygwin)
|
||||
* fixed cursor positioning cursor read answerback problem (Cygwin/Solaris)
|
||||
* fixed bug causing crash when progress displayed with too-small terminal
|
||||
|
||||
### 1.4.0 - 6 December 2012
|
||||
|
||||
* new option "`--skip-errors`" commissioned by Jim Salter
|
||||
* new option **--skip-errors** commissioned by Jim Salter
|
||||
* if stdout is a block device, and we don't know the total size, use the size of that block device as the total (Peter Samuelson)
|
||||
* new option "`--stop-at-size`" to stop after "`--size`" bytes
|
||||
* new option **--stop-at-size** to stop after **--size** bytes
|
||||
* report correct filename on read errors
|
||||
* fix use-after-free bug in remote PID cleanup code
|
||||
* refactored large chunks of code to make it more readable and to replace most static variables with a state structure
|
||||
|
||||
### 1.3.9 - 5 November 2012
|
||||
|
||||
* allow "`--format`" parameters to be sent with "`--remote`"
|
||||
* configure option "`--disable-ipc`"
|
||||
* added tests for "`--numeric`" with "`--timer`" and "`--bytes`"
|
||||
* added tests for "`--remote`"
|
||||
* allow **--format** parameters to be sent with **--remote**
|
||||
* configure option **--disable-ipc**
|
||||
* added tests for **--numeric** with **--timer** and **--bytes**
|
||||
* added tests for **--remote**
|
||||
|
||||
### 1.3.8 - 29 October 2012
|
||||
|
||||
* new "`--pidfile`" option to save process ID to a file
|
||||
* integrated patch for "`--numeric`" with "`--timer`" and "`--bytes`" (Sami Liedes)
|
||||
* removed signalling from "`--remote`" to prevent accidental process kills
|
||||
* new "`--format`" option (originally Vladimir Pal / Vladimir Ermakov)
|
||||
* new **--pidfile** option to save process ID to a file
|
||||
* integrated patch for **--numeric** with **--timer** and **--bytes** (Sami Liedes)
|
||||
* removed signalling from **--remote** to prevent accidental process kills
|
||||
* new **--format** option (originally Vladimir Pal / Vladimir Ermakov)
|
||||
|
||||
### 1.3.4 - 27 June 2012
|
||||
|
||||
* new "`--disable-splice`" configure script option
|
||||
* new **--disable-splice** configure script option
|
||||
* fixed line mode size count with multiple files (Moritz Barsnick)
|
||||
* fixes for AIX core dumps (Pawel Piatek)
|
||||
|
||||
@@ -261,10 +321,10 @@ Full changelog is below:
|
||||
|
||||
### 1.2.0 - 14 December 2010
|
||||
|
||||
* integrated improved SI prefixes and "`--average-rate`" (Henry Gebhardt)
|
||||
* integrated improved SI prefixes and **--average-rate** (Henry Gebhardt)
|
||||
* return nonzero if exiting due to *SIGTERM* (Martin Baum)
|
||||
* patch from Phil Rutschman to restore terminal properly on exit
|
||||
* fix i18n especially for "`--help`" (Sebastian Kayser)
|
||||
* fix i18n especially for **--help** (Sebastian Kayser)
|
||||
* refactored `pv_display`
|
||||
* we now have a coherent, documented, exit status
|
||||
* modified pipe test and new cksum test from Sebastian Kayser
|
||||
@@ -278,13 +338,13 @@ Full changelog is below:
|
||||
* patch from Elias Pipping correcting compilation failure on Darwin 9
|
||||
* patch from Patrick Collison correcting similar problems on OS X
|
||||
* trap *SIGINT* / *SIGHUP* / *SIGTERM* so we clean up IPCs on exit (Laszlo Ersek)
|
||||
* abort if numeric option, eg "`-L`", has non-numeric value (Boris Lohner)
|
||||
* abort if numeric option, eg **-L**, has non-numeric value (Boris Lohner)
|
||||
|
||||
### 1.1.0 - 30 August 2007
|
||||
|
||||
* new option "`--remote`" ("`-R`") to control an already-running process
|
||||
* new option "`--line-mode`" ("`-l`") to count lines instead of bytes
|
||||
* fix for "`-L`" to be less resource intensive
|
||||
* new option **--remote** (**-R**) to control an already-running process
|
||||
* new option **--line-mode** (**-l**) to count lines instead of bytes
|
||||
* fix for **-L** to be less resource intensive
|
||||
* fix for input/output equivalence check on Mac OS X
|
||||
* fix for size calculation in pipelines on Mac OS X
|
||||
* fixed "`make uninstall`"
|
||||
@@ -293,7 +353,7 @@ Full changelog is below:
|
||||
### 1.0.1 - 4 August 2007
|
||||
|
||||
* licensing change from Artistic to Artistic 2.0
|
||||
* removed the "`-l`" / "`--license`" option
|
||||
* removed the **-l** / **--license** option
|
||||
|
||||
### 1.0.0 - 2 August 2007
|
||||
|
||||
@@ -303,7 +363,7 @@ Full changelog is below:
|
||||
|
||||
### 0.9.9 - 5 February 2007
|
||||
|
||||
* new option "`--buffer-size`" ("`-B`") suggested by Mark Tomich
|
||||
* new option **--buffer-size** (**-B**) suggested by Mark Tomich
|
||||
* build fix: HP/UX largefile compile fix from Timo Savinen
|
||||
* maintain better buffer filling during transfers
|
||||
* workaround: "`pv /dev/zero | dd bs=1M count=1k`" bug (reported by Gert Menke)
|
||||
@@ -312,7 +372,7 @@ Full changelog is below:
|
||||
### 0.9.6 - 27 February 2006
|
||||
|
||||
* bugfix: `key_t` incompatibility with Cygwin
|
||||
* bugfix: interval ("`-i`") parameter parses numbers after decimal point
|
||||
* bugfix: interval (**-i**) parameter parses numbers after decimal point
|
||||
* build fix: use static NLS if `msgfmt` is unavailable
|
||||
* on the final update, blank out the now-zero ETA
|
||||
|
||||
@@ -330,7 +390,7 @@ Full changelog is below:
|
||||
|
||||
### 0.8.9 - 6 November 2004
|
||||
|
||||
* decimal values now accepted for rate and size, eg "`-L 1.23M`"
|
||||
* decimal values now accepted for rate and size, eg **-L 1.23M**
|
||||
* code cleanup
|
||||
* developers: "`make help`" now lists Makefile targets
|
||||
|
||||
@@ -340,9 +400,9 @@ Full changelog is below:
|
||||
|
||||
### 0.8.5 - 2 May 2004
|
||||
|
||||
* cursor positioning ("`-c`") reliability improved on systems with IPC
|
||||
* cursor positioning (**-c**) reliability improved on systems with IPC
|
||||
* minor fix: made test 005 more reliable
|
||||
* new option "`--height`" ("`-H`")
|
||||
* new option **--height** (**-H**)
|
||||
|
||||
### 0.8.2 - 24 April 2004
|
||||
|
||||
@@ -351,7 +411,7 @@ Full changelog is below:
|
||||
|
||||
### 0.8.1 - 19 April 2004
|
||||
|
||||
* bugfix in cursor positioning ("`-c`")
|
||||
* bugfix in cursor positioning (**-c**)
|
||||
|
||||
### 0.8.0 - 12 February 2004
|
||||
|
||||
@@ -363,7 +423,7 @@ Full changelog is below:
|
||||
### 0.7.0 - 8 February 2004
|
||||
|
||||
* display buffer management fixes (thanks Cédric Delfosse)
|
||||
* replaced "`--enable-debug`" with "`--enable-debugging`" and "`--enable-profiling`"
|
||||
* replaced **--enable-debug** with **--enable-debugging** and **--enable-profiling**
|
||||
|
||||
### 0.6.4 - 14 January 2004
|
||||
|
||||
@@ -427,11 +487,11 @@ Full changelog is below:
|
||||
|
||||
* allow decimal interval values, eg 0.1, 0.5, etc
|
||||
* some simple tests added ("`make check`")
|
||||
* smoother throughput limiting ("`--rate-limit`"), now done in 0.1sec chunks
|
||||
* bounds-check interval values ("`-i`") - max update interval now 10 minutes
|
||||
* smoother throughput limiting (**--rate-limit**), now done in 0.1sec chunks
|
||||
* bounds-check interval values (**-i**) - max update interval now 10 minutes
|
||||
* more reliable non-blocking output to keep display updated
|
||||
* no longer rely on `atoll()`
|
||||
* don't output final blank line if "`--numeric`"
|
||||
* don't output final blank line if **--numeric**
|
||||
* use `fcntl()` instead of `flock()` for Solaris compatibility
|
||||
|
||||
### 0.3.0 - 25 November 2002
|
||||
@@ -444,11 +504,11 @@ Full changelog is below:
|
||||
* we now ignore *EINTR* on `select()`
|
||||
* variable-size buffer (still need to add code to change size)
|
||||
* added (tentative) support for internationalisation
|
||||
* removed superfluous "`--no-progress`", etc options
|
||||
* removed superfluous **--no-progress**, etc options
|
||||
* optimised transfer by using bigger buffers, based on `st_blksize`
|
||||
* added "`--wait`" option to wait until transfer begins before showing progress
|
||||
* added "`--rate-limit`" option to limit rate to a maximum throughput
|
||||
* added "`--quiet`" option (no output at all) to be used with "`--rate-limit`"
|
||||
* added **--wait** option to wait until transfer begins before showing progress
|
||||
* added **--rate-limit** option to limit rate to a maximum throughput
|
||||
* added **--quiet** option (no output at all) to be used with **--rate-limit**
|
||||
|
||||
### 0.2.5 - 23 July 2002
|
||||
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
Things still to do. (#n) indicates the issue tracker number.
|
||||
|
||||
* ([#3](https://codeberg.org/a-j-wood/pv/issues/3)) Option ("`-x`"?) to use xterm title line for status (Joachim Haga)
|
||||
* ([#4](https://codeberg.org/a-j-wood/pv/issues/4)) Option for process title (Martin Sarsale) as "`pv - name:FooProcess -xyz - transferred: 1.3GB - 500KB/s - running: 10:15:30s`"
|
||||
* ([#6](https://codeberg.org/a-j-wood/pv/issues/6)) Look at effect of *O_SYNC* or `fsync` on performance; update counters during buffer flush
|
||||
* ([#9](https://codeberg.org/a-j-wood/pv/issues/9)) Option to switch rate to per minute if really slow
|
||||
* ([#10](https://codeberg.org/a-j-wood/pv/issues/10)) Add watchfd tests
|
||||
* ([#11](https://codeberg.org/a-j-wood/pv/issues/11)) Option "`--progress-from FILE`", read last number and use it as bytes read (Jacek Wielemborek)
|
||||
* ([#12](https://codeberg.org/a-j-wood/pv/issues/12)) Allow multiple "`-d`" options (Linus Heckemann for multiple PID:FD; Jacek Wielemborek)
|
||||
* ([#15](https://codeberg.org/a-j-wood/pv/issues/15)) Use Unicode for more granular progress bar (Alexander Petrossian)
|
||||
* ([#17](https://codeberg.org/a-j-wood/pv/issues/17)) Allow "`-r`" with "`-l`" and "`-n`" to output lines/sec (Roland Kletzing)
|
||||
* ([#22](https://codeberg.org/a-j-wood/pv/issues/22)) Options to skip input and seek on output (Jason A. Pfeil, Feb 2022)
|
||||
* ([#25](https://codeberg.org/a-j-wood/pv/issues/25)) Normalise progress to 100% on overrun (Andrej Gantvorg)
|
||||
* ([#34](https://codeberg.org/a-j-wood/pv/issues/34)) Continue timer even if input or output is blocking (Martin Probst - Jun 2017)
|
||||
* ([#35](https://codeberg.org/a-j-wood/pv/issues/35)) Allow decimal values for "`-s`", "`-L`", "`-B`" (Thomas Watson - Aug 2020)
|
||||
* ([#38](https://codeberg.org/a-j-wood/pv/issues/38)) Reset ETA on *SIGUSR1* (Jacek Wielemborek - Jan 2019)
|
||||
* ([#40](https://codeberg.org/a-j-wood/pv/issues/40)) Permit "`-c`" with "`-d PID:FD`", reject "`-N`" with "`-d PID`" (Norman Rasmussen - Nov 2020)
|
||||
* ([#43](https://codeberg.org/a-j-wood/pv/issues/43)) Differentiate between "`--eta`" and "`--fineta`" in display (André Stapf - Apr 2017)
|
||||
* ([#45](https://codeberg.org/a-j-wood/pv/issues/45)) Option "`--sparse`" (with block size option) to write sparse output (Andriy Galetski - Apr 2019)
|
||||
* ([#46](https://codeberg.org/a-j-wood/pv/issues/46)) Option to show speed gauge (% max speed) if progress not known (Ryan Cooley - Jun 2019)
|
||||
* ([#47](https://codeberg.org/a-j-wood/pv/issues/47)) Analyse splice and buffer usage to improve performance
|
||||
* ([#48](https://codeberg.org/a-j-wood/pv/issues/48)) Option to show multiple files with individual sizes and a cumulative total (Zach Riggle - Jul 2021)
|
||||
* ([#49](https://codeberg.org/a-j-wood/pv/issues/49)) Option to provide stats for avg/min/max/stddev throughput (Venky.N.Iyer)
|
||||
* ([#50](https://codeberg.org/a-j-wood/pv/issues/50)) Allow pv to report on a whole pipeline at once (Will Entriken - Feb 2011)
|
||||
* ([#54](https://codeberg.org/a-j-wood/pv/issues/54)) Run command every n percent ([haarp](https://github.com/haarp))
|
||||
* ([#56](https://codeberg.org/a-j-wood/pv/issues/56)) Support for backgrounding pv, and allowing it to be monitored separately ([jimbobmcgee](https://github.com/jimbobmcgee))
|
||||
* ([#67](https://codeberg.org/a-j-wood/pv/issues/67)) Wrap another process to monitor its stdin & stdout ([Alex Mason](https://github.com/axman6))
|
||||
* ([#76](https://codeberg.org/a-j-wood/pv/issues/76)) Provide a way to test translations without installing
|
||||
|
||||
Any assistance would be appreciated.
|
||||
@@ -35,5 +35,3 @@ for ((buffer=100; buffer<=1000; buffer+=100)); do
|
||||
echo -e "${buffer}\t${rate}\t${rdata}\t${wdata}"
|
||||
done
|
||||
done
|
||||
|
||||
# EOF
|
||||
|
||||
+354
-227
@@ -4,84 +4,65 @@ pv - monitor the progress of data through a pipe
|
||||
|
||||
# SYNOPSIS
|
||||
|
||||
**pv** \[*OPTION*\] \[*FILE*\]\...\
|
||||
**pv** \[*-h*\|*-V*\]
|
||||
**pv** \[*OPTION*\]\... \[*FILE*\]\...
|
||||
|
||||
**pv** \[ **-pteIrab8kTv** \] \[ **-A** NUM \] \[ **-F** FORMAT \] \[
|
||||
**-x** SPEC \] \[ **-Wgl0fc** \] \[ **-D** SEC \] \[ **-s** SIZE \] \[
|
||||
**-i** SEC \] \[ **-m** SEC \] \[ **-w** WIDTH \] \[ **-H** HEIGHT \] \[
|
||||
**-N** NAME \] \[ **-o** FILE \] \[ **-L** RATE \] \[ **-B** BYTES \] \[
|
||||
**-CESYKX** \] \[ **-Z** BYTES \] \[ **-U** FILE \] \[ **-P** FILE \]
|
||||
[*FILE* . . .\]
|
||||
|
||||
**pv** **-n** \[ **-trbv** \] \[ **-Wl0** \] \[ **-D** SEC \] \[ **-s**
|
||||
SIZE \] \[ **-i** SEC \] \[ **-o** FILE \] \[ **-L** RATE \] \[ **-B**
|
||||
BYTES \] \[ **-CESYKX** \] \[ **-Z** BYTES \] \[ **-U** FILE \] \[
|
||||
**-P** FILE \] \[*FILE* . . .\]
|
||||
|
||||
**pv** **-q** \[ **-v** \] \[ **-s** SIZE \] \[ **-o** FILE \] \[ **-L**
|
||||
RATE \] \[ **-B** BYTES \] \[ **-CESYKX** \] \[ **-Z** BYTES \] \[
|
||||
**-U** FILE \] \[ **-P** FILE \] \[*FILE* . . .\]
|
||||
|
||||
**pv** **-R** *PID* \[ **-pteIrabT** \] \[ **-A** NUM \] \[ **-F**
|
||||
FORMAT \] \[ **-s** SIZE \] \[ **-i** SEC \] \[ **-w** WIDTH \] \[
|
||||
**-H** HEIGHT \] \[ **-N** NAME \] \[ **-L** RATE \] \[ **-B** BYTES \]
|
||||
|
||||
**pv** **-d** *PID:FD* \[ **-pteIrab8kTnq** \] \[ **-F** FORMAT \] \[
|
||||
**-i** SEC \] \[ **-w** WIDTH \] \[ **-H** HEIGHT \]
|
||||
|
||||
**pv** **-d** *PID* \[ **-pteIrab8kTnq** \] \[ **-F** FORMAT \] \[
|
||||
**-i** SEC \] \[ **-w** WIDTH \] \[ **-H** HEIGHT \]
|
||||
|
||||
**pv** **-h**
|
||||
|
||||
**pv** **-V**
|
||||
|
||||
# DESCRIPTION
|
||||
|
||||
**pv** shows the progress of data through a pipeline by giving
|
||||
information such as time elapsed, percentage completed (with progress
|
||||
bar), current throughput rate, total data transferred, and ETA.
|
||||
Show the progress of data through a pipeline by giving information such
|
||||
as time elapsed, percentage completed (with progress bar), current
|
||||
throughput rate, total data transferred, and ETA.
|
||||
|
||||
To use it, insert it in a pipeline between two processes, with the
|
||||
appropriate options. Its standard input will be passed through to its
|
||||
standard output and progress will be shown on standard error.
|
||||
|
||||
**pv** will copy each supplied *FILE* in turn to standard output (**-**
|
||||
means standard input), or if no *FILE*s are specified just standard
|
||||
input is copied. This is the same behaviour as **cat**(1).
|
||||
|
||||
A simple example to watch how quickly a file is transferred using
|
||||
**nc**(1):
|
||||
|
||||
> **pv file \| nc -w 1 somewhere.com 3000**
|
||||
|
||||
A similar example, transferring a file from another process and passing
|
||||
the expected size to **pv**:
|
||||
|
||||
> **cat file \| pv -s 12345 \| nc -w 1 somewhere.com 3000**
|
||||
|
||||
A more complicated example using numeric output to feed into the
|
||||
**dialog**(1) program for a full-screen progress display:
|
||||
|
||||
> **(tar cf - . \\**\
|
||||
> ** \| pv -n -s \$(du -sb . \| awk \'{print \$1}\') \\**\
|
||||
> ** \| gzip -9 \> out.tgz) 2\>&1 \\**\
|
||||
> **\| dialog \--gauge \'Progress\' 7 70**
|
||||
|
||||
Taking an image of a disk, skipping errors:
|
||||
|
||||
> **pv -EE /dev/your/disk/device \> disk-image.img**
|
||||
|
||||
Writing an image back to a disk:
|
||||
|
||||
> **pv disk-image.img \> /dev/your/disk/device**
|
||||
|
||||
Zeroing a disk:
|
||||
|
||||
> **pv \< /dev/zero \> /dev/your/disk/device**
|
||||
|
||||
Note that if the input size cannot be calculated, and the output is a
|
||||
block device, then the size of the block device will be used and **pv**
|
||||
will automatically stop at that size as if **-S** had been given.
|
||||
|
||||
(Linux only): Watching file descriptor 3 opened by another process 1234:
|
||||
|
||||
> **pv -d 1234:3**
|
||||
|
||||
(Linux only): Watching all file descriptors used by process 1234:
|
||||
|
||||
> **pv -d 1234**
|
||||
Each *FILE* is copied to standard output. With no *FILE*, or when *FILE*
|
||||
is "-", standard input is read. This is the same behaviour as
|
||||
**cat**(1).
|
||||
|
||||
# OPTIONS
|
||||
|
||||
**pv** takes many options, which are divided into display switches,
|
||||
output modifiers, and general options.
|
||||
## Display switches
|
||||
|
||||
# DISPLAY SWITCHES
|
||||
|
||||
If no display switches are specified, **pv** behaves as if **-p**,
|
||||
**-t**, **-e**, **-r**, and **-b** had been given (i.e. everything
|
||||
except average rate is switched on). Otherwise, only those display types
|
||||
that are explicitly switched on will be shown.
|
||||
If no display switches are specified, **pv** behaves as if
|
||||
"**\--progress**", "**\--timer**", "**\--eta**", "**\--rate**", and
|
||||
"**\--bytes**" had been given. Otherwise, only those display types that
|
||||
are explicitly switched on will be shown.
|
||||
|
||||
**-p, \--progress**
|
||||
|
||||
: Turn the progress bar on. If any inputs are not files, or are
|
||||
unreadable, and no size was explicitly given (with the **-s**
|
||||
modifier), the progress bar cannot indicate how close to completion
|
||||
the transfer is, so it will just move left and right to indicate
|
||||
that data is moving.
|
||||
unreadable, and no size was explicitly given with "**\--size**", the
|
||||
progress bar cannot indicate how close to completion the transfer
|
||||
is, so it will just move left and right to indicate that data is
|
||||
moving - or, with "**\--gauge**", the bar will indicate the current
|
||||
rate as a percentage of the maximum rate seen so far.
|
||||
|
||||
**-t, \--timer**
|
||||
|
||||
@@ -90,136 +71,153 @@ that are explicitly switched on will be shown.
|
||||
|
||||
**-e, \--eta**
|
||||
|
||||
: Turn the ETA timer on. This will attempt to guess, based on current
|
||||
: Turn the ETA countdown on. This will estimate, based on current
|
||||
transfer rates and the total data size, how long it will be before
|
||||
completion. This option will have no effect if the total data size
|
||||
cannot be determined.
|
||||
completion. The countdown is prefixed with "ETA". This option will
|
||||
have no effect if the total data size cannot be determined.
|
||||
|
||||
**-I, \--fineta**
|
||||
|
||||
: Turn the ETA timer on, but display the estimated local time of
|
||||
arrival instead of time left. When the estimated time is more than 6
|
||||
hours in the future, the date is shown as well.
|
||||
: Turn the ETA countdown on, but display the estimated local time at
|
||||
which the transfer will finish, instead of the amount of time
|
||||
remaining. When the estimated time is more than 6 hours in the
|
||||
future, the date is shown as well. The time is prefixed with "FIN"
|
||||
for finish time. As with "**\--eta**", this option will have no
|
||||
effect if the total data size cannot be determined.
|
||||
|
||||
**-r, \--rate**
|
||||
|
||||
: Turn the rate counter on. This will display the current rate of data
|
||||
transfer.
|
||||
transfer. The rate is shown in square brackets "\[\]".
|
||||
|
||||
**-a, \--average-rate**
|
||||
|
||||
: Turn the average rate counter on. This will display the current
|
||||
average rate of data transfer (default: last 30s, see **-m**).
|
||||
average rate of data transfer, over the last 30 seconds by default
|
||||
(see "**\--average-rate-window**"). The average rate is shown in
|
||||
brackets "()".
|
||||
|
||||
**-b, \--bytes**
|
||||
|
||||
: Turn the total byte counter on. This will display the total amount
|
||||
of data transferred so far.
|
||||
|
||||
**-8, \--bits**
|
||||
|
||||
: Display the total bits instead of the total bytes. The output suffix
|
||||
will be \"b\" instead of \"B\".
|
||||
|
||||
**-T, \--buffer-percent**
|
||||
|
||||
: Turn on the transfer buffer percentage display. This will show the
|
||||
percentage of the transfer buffer in use - but see the caveat under
|
||||
**%T** in the **FORMATTING** section below. Implies **-C**.
|
||||
percentage of the transfer buffer in use. Implies
|
||||
"**\--no-splice**". The transfer buffer percentage is shown in curly
|
||||
brackets "{}".
|
||||
|
||||
**-A NUM, \--last-written NUM**
|
||||
|
||||
: Show the last *NUM* bytes written - but see the caveat under **%nA**
|
||||
in the **FORMATTING** section below. Implies **-C**.
|
||||
: Show the last *NUM* bytes written. Implies "**\--no-splice**".
|
||||
|
||||
**-F FORMAT, \--format FORMAT**
|
||||
|
||||
: Ignore the options **-p**, **-t**, **-e**, **-r**, **-a**, **-b**,
|
||||
**-T**, and **-A**, and instead use the format string *FORMAT* to
|
||||
determine the output format. See the **FORMATTING** section below.
|
||||
: Ignore all of the above options and instead use the format string
|
||||
*FORMAT* to determine the output format. See the **FORMATTING**
|
||||
section below.
|
||||
|
||||
**-n, \--numeric**
|
||||
|
||||
: Numeric output. Instead of giving a visual indication of progress,
|
||||
**pv** will give an integer percentage, one per line, on standard
|
||||
error, suitable for piping (via convoluted redirection) into
|
||||
**dialog**(1). Note that **-f** is not required if **-n** is being
|
||||
used.
|
||||
write an integer percentage, one per line, on standard error,
|
||||
suitable for passing to a tool such as **dialog**(1). Note that
|
||||
"**\--force**" is not required if "**\--numeric**" is being used.
|
||||
|
||||
: Note that if **\--numeric** is in use, then adding **\--bytes** will
|
||||
cause the number of bytes processed so far to be output instead of a
|
||||
percentage; if **\--line-mode** is also in use as well as
|
||||
**\--bytes** and **\--numeric**, then instead of bytes or a
|
||||
percentage, the number of lines so far is output. And finally, if
|
||||
**\--timer** is added to **\--numeric**, then each output line is
|
||||
prefixed with the elapsed time so far, as a decimal number of
|
||||
seconds.
|
||||
: Combining "**\--numeric**" with "**\--bytes**" will cause the number
|
||||
of bytes processed so far to be output instead of a percentage.
|
||||
Adding "**\--line-mode**" as well as "**\--bytes**" writes the
|
||||
number of lines instead of bytes or a percentage. Adding
|
||||
"**\--rate**" adds the transfer rate to each output line (if
|
||||
"**\--bytes**" is also in use, the rate comes after the byte/line
|
||||
count). Adding "**\--timer**" prefixes each output line with the
|
||||
elapsed time so far, as a decimal number of seconds.
|
||||
|
||||
**-q, \--quiet**
|
||||
|
||||
: No output. Useful if the **-L** option is being used on its own to
|
||||
just limit the transfer rate of a pipe.
|
||||
: No output. Useful if the "**\--rate-limit**" option is being used on
|
||||
its own to limit the transfer rate of a pipe.
|
||||
|
||||
# OUTPUT MODIFIERS
|
||||
## Output modifiers
|
||||
|
||||
**-8, \--bits**
|
||||
|
||||
: Use bits instead of bytes for the byte and rate counters. The output
|
||||
suffix will be "b" instead of "B".
|
||||
|
||||
**-k, \--si**
|
||||
|
||||
: Display and interpret suffixes as multiples of 1000 rather than the
|
||||
default of 1024. Note that this only takes effect on options after
|
||||
this one, so for consistency, specify this option first.
|
||||
|
||||
**-W, \--wait**
|
||||
|
||||
: Wait until the first byte has been transferred before showing any
|
||||
progress information or calculating any ETAs. Useful if the program
|
||||
you are piping to or from requires extra information before it
|
||||
starts, eg piping data into **gpg**(1) or **mcrypt**(1) which
|
||||
require a passphrase before data can be processed.
|
||||
starts, such as when piping data into **gpg**(1) or **mcrypt**(1)
|
||||
which require a passphrase before data can be processed.
|
||||
|
||||
**-D SEC, \--delay-start SEC**
|
||||
|
||||
: Wait until *SEC* seconds have passed before showing any progress
|
||||
information, for example in a script where you only want to show a
|
||||
progress bar if it starts taking a long time. Note that this can be
|
||||
a decimal such as 0.5.
|
||||
progress bar if it starts taking a long time. The value of *SEC* can
|
||||
be a decimal such as "0.5".
|
||||
|
||||
**-s SIZE, \--size SIZE**
|
||||
|
||||
: Assume the total amount of data to be transferred is *SIZE* bytes
|
||||
when calculating percentages and ETAs. The same suffixes of \"k\",
|
||||
\"m\" etc can be used as with **-L**.
|
||||
when calculating percentages and ETAs. A suffix of "K", "M", "G", or
|
||||
"T" can be added to denote kibibytes (\*1024), mebibytes, gibibytes,
|
||||
tebibytes. If "**\--si**" appears before this option, suffixes will
|
||||
denote kilobytes (\*1000), megabytes, and so on instead.
|
||||
|
||||
: If *SIZE* starts with **@**, the size of file whose name follows the
|
||||
**@** will be used.
|
||||
: If *SIZE* starts with "**@**", the size of file whose name follows
|
||||
the @ will be used.
|
||||
|
||||
: Note that **\--size** has no effect if used with **-d ***PID* to
|
||||
watch all file descriptors of a process, but will work with **-d
|
||||
PID:FD**.
|
||||
:
|
||||
|
||||
**-g, \--gauge**
|
||||
|
||||
: If the progress bar is shown but the size is not known, then instead
|
||||
of moving the bar left and right to show progress, show the current
|
||||
transfer rate as a percentage of the maximum rate seen so far.
|
||||
|
||||
**-l, \--line-mode**
|
||||
|
||||
: Instead of counting bytes, count lines (newline characters). The
|
||||
progress bar will only move when a new line is found, and the value
|
||||
passed to the **-s** option will be interpreted as a line count.
|
||||
passed to "**\--size**" will be interpreted as a line count.
|
||||
|
||||
: If this option is used without **-s**, the \"total size\" (in this
|
||||
case, total line count) is calculated by reading through all input
|
||||
files once before transfer starts. If any inputs are pipes or
|
||||
: If this option is used without "**\--size**", the \"total size\" (in
|
||||
this case, total line count) is calculated by reading through all
|
||||
input files once before transfer starts. If any inputs are pipes or
|
||||
non-regular files, or are unreadable, the total size will not be
|
||||
calculated.
|
||||
|
||||
**-0, \--null**
|
||||
|
||||
: Count lines as terminated with a zero byte instead of with a
|
||||
newline. This option implies \--line-mode.
|
||||
: Count lines as terminated with a null byte instead of with a
|
||||
newline. This option implies "**\--line-mode**".
|
||||
|
||||
**-i SEC, \--interval SEC**
|
||||
|
||||
: Wait *SEC* seconds between updates. The default is to update every
|
||||
second. Note that this can be a decimal such as 0.1.
|
||||
second. The value of *SEC* can be a decimal such as "0.1".
|
||||
|
||||
**-m SEC, \--average-rate-window SEC**
|
||||
|
||||
: Compute current average rate over a *SEC* seconds window for average
|
||||
rate and ETA calculations (default 30 seconds).
|
||||
rate and ETA calculations. The default is 30 seconds. The value must
|
||||
be an integer.
|
||||
|
||||
**-w WIDTH, \--width WIDTH**
|
||||
|
||||
: Assume the terminal is *WIDTH* characters wide, instead of trying to
|
||||
: Assume the terminal is *WIDTH* columns wide, instead of trying to
|
||||
work it out (or assuming 80 if it cannot be guessed). If this option
|
||||
is used, the output width will not be adjusted if the width of the
|
||||
terminal changes while the transfer is running.
|
||||
@@ -234,8 +232,28 @@ that are explicitly switched on will be shown.
|
||||
**-N NAME, \--name NAME**
|
||||
|
||||
: Prefix the output information with *NAME*. Useful in conjunction
|
||||
with **-c** if you have a complicated pipeline and you want to be
|
||||
able to tell different parts of it apart.
|
||||
with "**\--cursor**" if you have a complicated pipeline and you want
|
||||
to be able to tell different parts of it apart.
|
||||
|
||||
**-x SPEC, \--extra-display SPEC**
|
||||
|
||||
: As well as displaying progress to the terminal, also write it to
|
||||
*SPEC*. The *SPEC* must start with a comma-separated list of
|
||||
destinations, and can optionally be followed by a colon and a format
|
||||
string. The destinations can be **windowtitle** or **window** for
|
||||
the xterm window title, and **processtitle**, **proctitle**,
|
||||
**process**, or **proc** for the process title displayed by
|
||||
**ps**(1). If a format string is not supplied, the same format is
|
||||
used as for the terminal. For example,
|
||||
"**-x \'window,process:%t %b %r\'**" will show the elapsed time,
|
||||
bytes transferred, and rate, in both the window title and the
|
||||
process title.
|
||||
|
||||
**-v, \--stats**
|
||||
|
||||
: At the end of the transfer, write an additional line showing the
|
||||
transfer rate minimum, maximum, mean, and standard deviation. The
|
||||
values are always in bytes per second (or bits, with "**\--bits**").
|
||||
|
||||
**-f, \--force**
|
||||
|
||||
@@ -245,27 +263,29 @@ that are explicitly switched on will be shown.
|
||||
**-c, \--cursor**
|
||||
|
||||
: Use cursor positioning escape sequences instead of just using
|
||||
carriage returns. This is useful in conjunction with **-N** (name)
|
||||
if you are using multiple **pv** invocations in a single, long,
|
||||
pipeline.
|
||||
carriage returns. This is useful in conjunction with "**\--name**"
|
||||
if you are using multiple **pv** invocations in a single pipeline.
|
||||
|
||||
# DATA TRANSFER MODIFIERS
|
||||
## Data transfer modifiers
|
||||
|
||||
**-o FILE, \--output FILE**
|
||||
|
||||
: Write data to *FILE* instead of standard output. If the file already
|
||||
exists, it will be truncated.
|
||||
|
||||
**-L RATE, \--rate-limit RATE**
|
||||
|
||||
: Limit the transfer to a maximum of *RATE* bytes per second. A suffix
|
||||
of \"K\", \"M\", \"G\", or \"T\" can be added to denote kibibytes
|
||||
(\*1024), mebibytes, and so on.
|
||||
: Limit the transfer to a maximum of *RATE* bytes per second. The same
|
||||
suffixes as "**\--size**" can be used.
|
||||
|
||||
**-B BYTES, \--buffer-size BYTES**
|
||||
|
||||
: Use a transfer buffer size of *BYTES* bytes. A suffix of \"K\",
|
||||
\"M\", \"G\", or \"T\" can be added to denote kibibytes (\*1024),
|
||||
mebibytes, and so on. The default buffer size is the block size of
|
||||
the input file\'s filesystem multiplied by 32 (512KiB max), or
|
||||
: Use a transfer buffer size of *BYTES* bytes. The same suffixes as
|
||||
"**\--size**" can be used. The default buffer size is the block size
|
||||
of the input file\'s filesystem multiplied by 32 (512KiB max), or
|
||||
400KiB if the block size cannot be determined. This can be useful on
|
||||
platforms like MacOS which perform better in pipelines with specific
|
||||
buffer sizes such as 1024. Implies **-C**.
|
||||
platforms like MacOS with pipelines that perform better with
|
||||
specific buffer sizes such as 1024. Implies "**\--no-splice**".
|
||||
|
||||
**-C, \--no-splice**
|
||||
|
||||
@@ -273,11 +293,12 @@ that are explicitly switched on will be shown.
|
||||
**splice**(2) system call is a more efficient way of transferring
|
||||
data from or to a pipe than regular **read**(2) and **write**(2),
|
||||
but means that the transfer buffer may not be used. This prevents
|
||||
**-A** and **-T** from working, cannot work with **-X**, and makes
|
||||
**-B** redundant, so using **-A**, **-T**, **-X**, or **-B**
|
||||
automatically switches on **-C**. Switching on **-C** results in a
|
||||
small loss of transfer efficiency. (This option has no effect on
|
||||
systems where **splice**(2) is unavailable).
|
||||
"**\--buffer-percent**" and "**\--last-written**" from working,
|
||||
cannot work with "**\--discard**", and makes "**\--buffer-size**"
|
||||
redundant, so using any of those options automatically switches on
|
||||
"**\--no-splice**". Switching on this option results in a small loss
|
||||
of transfer efficiency. It has no effect on systems where
|
||||
**splice**(2) is unavailable.
|
||||
|
||||
**-E, \--skip-errors**
|
||||
|
||||
@@ -285,45 +306,46 @@ that are explicitly switched on will be shown.
|
||||
sections. The corresponding parts of the output will be null bytes.
|
||||
At first only a few bytes will be skipped, but if there are many
|
||||
errors in a row then the skips will move up to chunks of 512. This
|
||||
is intended to be similar to **dd conv=sync,noerror** but has not
|
||||
been as thoroughly tested.
|
||||
is intended to be similar to "*dd conv=sync,noerror*".
|
||||
|
||||
: Specify **-E** twice to only report a read error once per file,
|
||||
instead of reporting each byte range skipped.
|
||||
: Specify "**\--skip-errors**" twice to only report a read error once
|
||||
per file, instead of reporting each byte range skipped.
|
||||
|
||||
**-Z BYTES, \--error-skip-block BYTES**
|
||||
|
||||
: When ignoring read errors with **-E**, instead of trying to
|
||||
adaptively skip by reading small amounts and skipping progressively
|
||||
larger sections until a read succeeds, move to the next file block
|
||||
of *BYTES* bytes as soon as an error occurs. There may still be some
|
||||
shorter skips where the block being skipped coincides with the end
|
||||
of the transfer buffer.
|
||||
: When ignoring read errors with "**\--skip-errors**", instead of
|
||||
trying to adaptively skip by reading small amounts and skipping
|
||||
progressively larger sections until a read succeeds, move to the
|
||||
next file block of *BYTES* bytes as soon as an error occurs. There
|
||||
may still be some shorter skips where the block being skipped
|
||||
coincides with the end of the transfer buffer. The same suffixes as
|
||||
"**\--size**" can be used.
|
||||
|
||||
: This option can only be used with **-E** and is intended for use
|
||||
when reading from a block device, such as **-E -Z 4K** to skip in 4
|
||||
kibibyte blocks. This will speed up reads from faulty media, at the
|
||||
expense of potentially losing more data.
|
||||
: This option can only be used with "**\--skip-errors**" and is
|
||||
intended for use when reading from a block device, such as
|
||||
"**\--skip-errors \--error-skip-block 4K**" to skip in 4 kibibyte
|
||||
blocks. This will speed up reads from faulty media, at the expense
|
||||
of potentially losing more data.
|
||||
|
||||
**-S, \--stop-at-size**
|
||||
|
||||
: If a size was specified with **-s**, stop transferring data once
|
||||
that many bytes have been written, instead of continuing to the end
|
||||
of input.
|
||||
: If a size was specified with "**\--size**", stop transferring data
|
||||
once that many bytes have been written, instead of continuing to the
|
||||
end of input.
|
||||
|
||||
**-Y, \--sync**
|
||||
|
||||
: After every write operation, synchronise the buffer caches to disk -
|
||||
see **fdatasync**(2). This has no effect when the output is a pipe.
|
||||
Using **-Y** may improve the accuracy of the progress bar when
|
||||
writing to a slow disk.
|
||||
: After every write operation, synchronise the buffer caches to disk
|
||||
with **fdatasync**(2). This has no effect when the output is a pipe.
|
||||
Using "**\--sync**" may improve the accuracy of the progress bar
|
||||
when writing to a slow disk.
|
||||
|
||||
**-K, \--direct-io**
|
||||
|
||||
: Set the **O_DIRECT** flag on all inputs and outputs, if it is
|
||||
available. This will minimise the effect of caches, at the cost of
|
||||
performance. Due to memory alignment requirements, it also may cause
|
||||
read or write failures with an error of \"Invalid argument\",
|
||||
read or write failures with an error of "Invalid argument",
|
||||
especially if reading and writing files across a variety of
|
||||
filesystems in a single **pv** call. Use this option with caution.
|
||||
|
||||
@@ -331,7 +353,25 @@ that are explicitly switched on will be shown.
|
||||
|
||||
: Instead of transferring input data to standard output, discard it.
|
||||
This is equivalent to redirecting standard output to */dev/null*,
|
||||
except that **write**(2) is never called. Implies **-C**.
|
||||
except that **write**(2) is never called. Implies
|
||||
"**\--no-splice**".
|
||||
|
||||
**-U FILE, \--store-and-forward FILE**
|
||||
|
||||
: Instead of passing data through immediately, do it in two stages -
|
||||
first read all input and write it to *FILE*, and then once the input
|
||||
is exhausted, read all of *FILE* and write it to the output. *FILE*
|
||||
remains in place afterwards, unless it is "**-**", in which case
|
||||
**pv** creates a temporary file for this purpose, and automatically
|
||||
removes it afterwards.
|
||||
|
||||
: This can be useful if you have a pipeline which generates data (your
|
||||
input) quickly but you don\'t know the size, and you wish to pass it
|
||||
to some slower process, once all of the input has been generated and
|
||||
you know its size, so you can see its progress. Note that when doing
|
||||
this with relatively small amounts of data, "**\--no-splice**" may
|
||||
be preferable so that pipe buffering doesn\'t affect the progress
|
||||
display.
|
||||
|
||||
**-d PID\[:FD\], \--watchfd PID\[:FD\]**
|
||||
|
||||
@@ -347,22 +387,25 @@ that are explicitly switched on will be shown.
|
||||
|
||||
**-R PID, \--remote PID**
|
||||
|
||||
: If *PID* is an instance of **pv** that is already running, **-R
|
||||
***PID* will cause that instance to act as though it had been given
|
||||
this instance\'s command line instead. For example, if **pv -L
|
||||
123K** is running with process ID 9876, then running **pv -R 9876 -L
|
||||
321K** will cause it to start using a rate limit of 321KiB instead
|
||||
of 123KiB. Note that some options cannot be changed while running,
|
||||
such as **-c**, **-l**, **-f**, **-D**, **-E**, and **-S**.
|
||||
: Remotely control another instance of **pv** with process ID *PID*,
|
||||
making it act as though it had been given this instance\'s command
|
||||
line. For example, if "**pv \--rate-limit 123K**" is running with
|
||||
process ID 9876, then running
|
||||
"**pv \--remote 9876 \--rate-limit 321K**" will cause process 9876
|
||||
to start using a rate limit of 321KiB instead of 123KiB. Note that
|
||||
some options cannot be changed while running, such as
|
||||
"**\--cursor**", "**\--line-mode**", "**\--force**",
|
||||
"**\--delay-start**", "**\--skip-errors**", and
|
||||
"**\--stop-at-size**".
|
||||
|
||||
# GENERAL OPTIONS
|
||||
## General options
|
||||
|
||||
**-P FILE, \--pidfile FILE**
|
||||
|
||||
: Save the process ID of **pv** in *FILE*. The file will be replaced
|
||||
if it already exists, and will be removed when **pv** exits. While
|
||||
**pv** is running, it will contain a single number - the process ID
|
||||
of **pv** - followed by a newline.
|
||||
**pv** is running, *FILE* will contain a single number - the process
|
||||
ID of **pv** - followed by a newline.
|
||||
|
||||
**-h, \--help**
|
||||
|
||||
@@ -374,68 +417,70 @@ that are explicitly switched on will be shown.
|
||||
|
||||
# FORMATTING
|
||||
|
||||
If the **-F** option is given, then the output format is determined by
|
||||
the given format string. Within that string, the following sequences can
|
||||
be used:
|
||||
Format strings used by "**\--format**" and "**\--extra-display**" can
|
||||
contain the following sequences:
|
||||
|
||||
**%p**
|
||||
|
||||
: Progress bar. Expands to fill the remaining space. Should only be
|
||||
specified once. Equivalent to **-p**.
|
||||
specified once. Equivalent to "**\--progress**".
|
||||
|
||||
**%t**
|
||||
|
||||
: Elapsed time. Equivalent to **-t**.
|
||||
: Elapsed time. Equivalent to "**\--timer**".
|
||||
|
||||
**%e**
|
||||
|
||||
: ETA as time remaining. Equivalent to **-e**.
|
||||
: ETA as time remaining. Equivalent to "**\--eta**".
|
||||
|
||||
**%I**
|
||||
|
||||
: ETA as local time of completion. Equivalent to **-I**.
|
||||
: ETA as local time at which the transfer will finish. Equivalent to
|
||||
"**\--fineta**".
|
||||
|
||||
**%r**
|
||||
|
||||
: Current data transfer rate. Equivalent to **-r**.
|
||||
: Current data transfer rate. Equivalent to "**\--rate**".
|
||||
|
||||
**%a**
|
||||
|
||||
: Average data transfer rate. Equivalent to **-a**.
|
||||
: Average data transfer rate. Equivalent to "**\--average-rate**".
|
||||
|
||||
**%b**
|
||||
|
||||
: Bytes transferred so far (or lines if **-l** was specified).
|
||||
Equivalent to **-b**. If **\--bits** was specified, **%b** shows the
|
||||
bits transferred so far, not bytes.
|
||||
: Bytes transferred so far (or lines if "**\--line-mode**" was
|
||||
specified). Equivalent to "**\--bytes**". If "**\--bits**" was
|
||||
specified, "**%b**" shows the bits transferred so far, not bytes.
|
||||
|
||||
**%T**
|
||||
|
||||
: Percentage of the transfer buffer in use. Equivalent to **-T**.
|
||||
Shows \"{\-\-\--}\" if the transfer is being done with
|
||||
**splice**(2), since splicing to or from pipes does not use the
|
||||
buffer.
|
||||
: Percentage of the transfer buffer in use. Equivalent to
|
||||
"**\--buffer-percent**". Displays "{\-\-\--}" if the transfer is
|
||||
being done with **splice**(2), since splicing to or from pipes does
|
||||
not use the buffer.
|
||||
|
||||
**%nA**
|
||||
|
||||
: Show the last **n** bytes written (e.g. **%16A** for the last 16
|
||||
bytes). Shows only dots if the transfer is being done with
|
||||
: Show the last *n* bytes written (for example, "**%16A**" shows the
|
||||
last 16 bytes). Shows only dots if the transfer is being done with
|
||||
**splice**(2), since splicing to or from pipes does not use the
|
||||
buffer.
|
||||
|
||||
**%N**
|
||||
|
||||
: Name prefix given by **-N**. Padded to 9 characters with spaces, and
|
||||
suffixed with :.
|
||||
: Show the name prefix given by "**\--name**". Padded to 9 characters
|
||||
with spaces, and suffixed with ":".
|
||||
|
||||
**%%**
|
||||
|
||||
: A single %.
|
||||
: A single "%".
|
||||
|
||||
Any other contents are reproduced in the progress display as-is.
|
||||
|
||||
The format string equivalent of turning on all display switches is
|
||||
**\`%N %b %T %t %r %a %p %e\'**.
|
||||
"**%N %b %T %t %r %a %p %e %I %8A**".
|
||||
|
||||
# COMMON SWITCHES
|
||||
# EXAMPLES
|
||||
|
||||
Some suggested common switch combinations:
|
||||
|
||||
@@ -449,23 +494,73 @@ Some suggested common switch combinations:
|
||||
: Show a progress bar, elapsed time, estimated completion time, line
|
||||
counter, and average rate, counting lines instead of bytes.
|
||||
|
||||
**pv -btrpg**
|
||||
|
||||
: Show the amount transferred, elapsed time, current rate, and a gauge
|
||||
showing the current rate as a percentage of the maximum rate seen -
|
||||
useful in a pipeline where the total size is unknown. (If the size
|
||||
*is* known, these options will show the percentage completion
|
||||
instead of the rate gauge).
|
||||
|
||||
**pv -t**
|
||||
|
||||
: Show only the elapsed time - useful as a simple timer, e.g. **sleep
|
||||
10m \| pv -t**.
|
||||
: Show only the elapsed time - useful as a simple timer, such as
|
||||
"**sleep 10m \| pv -t**".
|
||||
|
||||
**pv -pterb**
|
||||
|
||||
: The default behaviour: progress bar, elapsed time, estimated
|
||||
completion time, current rate, and byte counter.
|
||||
|
||||
On MacOS, it may be useful to specify **-B 1024** in a pipeline, as this
|
||||
may improve performance.
|
||||
On MacOS, it may be useful to specify "**\--buffer-size 1024**" in a
|
||||
pipeline, as this may improve performance.
|
||||
|
||||
To watch how quickly a file is transferred using **nc**(1):
|
||||
|
||||
pv file | nc -w 1 somewhere.com 3000
|
||||
|
||||
A similar example, transferring a file from another process and passing
|
||||
the expected size to **pv**:
|
||||
|
||||
cat file | pv -s 12345 | nc -w 1 somewhere.com 3000
|
||||
|
||||
A more complicated example using numeric output to feed into the
|
||||
**dialog**(1) program for a full-screen progress display:
|
||||
|
||||
(tar cf - . \
|
||||
| pv -n -s $(du -sb . | awk '{print $1}') \
|
||||
| gzip -9 > out.tgz) 2>&1 \
|
||||
| dialog --gauge 'Progress' 7 70
|
||||
|
||||
Taking an image of a disk, skipping errors:
|
||||
|
||||
pv -EE /dev/your/disk/device > disk-image.img
|
||||
|
||||
Writing an image back to a disk:
|
||||
|
||||
pv disk-image.img > /dev/your/disk/device
|
||||
|
||||
Zeroing a disk:
|
||||
|
||||
pv < /dev/zero > /dev/your/disk/device
|
||||
|
||||
Note that if the input size cannot be calculated, and the output is a
|
||||
block device, then the size of the block device will be used and **pv**
|
||||
will automatically stop at that size as if "**\--stop-at-size**" had
|
||||
been given.
|
||||
|
||||
(Linux only): Watching file descriptor 3 opened by another process 1234:
|
||||
|
||||
pv -d 1234:3
|
||||
|
||||
(Linux only): Watching all file descriptors used by process 1234:
|
||||
|
||||
pv -d 1234
|
||||
|
||||
# EXIT STATUS
|
||||
|
||||
An exit status of 1 indicates a problem with the **-R** or **-P**
|
||||
options.
|
||||
An exit status of 1 indicates a problem with the "**\--remote**" or
|
||||
"**\--pidfile**" options.
|
||||
|
||||
Any other exit status is a bitmask of the following:
|
||||
|
||||
@@ -496,49 +591,81 @@ Any other exit status is a bitmask of the following:
|
||||
|
||||
A zero exit status indicates no problems.
|
||||
|
||||
# AUTHOR
|
||||
# ENVIRONMENT
|
||||
|
||||
Written by Andrew Wood, with patches submitted by various other people.
|
||||
Please see the package\'s ACKNOWLEDGEMENTS file for a complete list of
|
||||
contributors.
|
||||
The following environment variables may affect **pv**:
|
||||
|
||||
# KNOWN PROBLEMS
|
||||
**HOME**
|
||||
|
||||
The following problems are known to exist in **pv**:
|
||||
: The current user\'s home directory. This may be used by
|
||||
"**\--remote**" to exchange messages between **pv** instances: if
|
||||
the */run/user/UID/* directory does not exist (where *UID* is the
|
||||
current user ID), then *\$HOME/.pv/* will be used instead.
|
||||
|
||||
- In some versions of **bash**(1) and **zsh**(1), the construct
|
||||
**\<(pv filename)** will not output any progress to the terminal
|
||||
when run from an interactive shell, due to the subprocess being run
|
||||
in a separate process group from the one that owns the terminal. In
|
||||
these cases, use **\--force**.
|
||||
**TMPDIR**, **TMP**
|
||||
|
||||
- The **-c** option does not work properly on Cygwin without
|
||||
**cygserver** running, if started near the bottom of the screen (IPC
|
||||
is needed to handle the terminal scrolling). To fix this, start
|
||||
**cygserver** before using **pv -c**.
|
||||
: The directory to create per-tty lock files for the terminal when
|
||||
using "**\--cursor**". If **TMPDIR** is set to a non-empty value, it
|
||||
is the directory under which lock files are created. Otherwise,
|
||||
**TMP** is used. If neither are set, then */tmp* is used.
|
||||
|
||||
- The **-R** option requires that either **/run/user/\<uid\>/** or
|
||||
**\$HOME/** can be written to, for inter-process communication.
|
||||
# NOTES
|
||||
|
||||
If you find any other problems, please report them.
|
||||
In some versions of **bash**(1) and **zsh**(1), the construct
|
||||
"**\<(pv filename)**" will not output any progress to the terminal when
|
||||
run from an interactive shell, due to the subprocess being run in a
|
||||
separate process group from the one that owns the terminal. In these
|
||||
cases, use "**\--force**".
|
||||
|
||||
If **pv** is used in a pipeline in **zsh** version 5.8, and the last
|
||||
command in the pipeline is based on shell builtins, **zsh** takes
|
||||
control of the terminal away from **pv**, preventing progress from being
|
||||
displayed. For example, this will produce no progress bar:
|
||||
|
||||
pv InputFile | { while read -r line; do sleep 0.1; done; }
|
||||
|
||||
To work around this, put the last commands of the pipeline in normal
|
||||
brackets to force the use of a subshell:
|
||||
|
||||
pv InputFile | ( while read -r line; do sleep 0.1; done; )
|
||||
|
||||
Refer to [issue #105](https://codeberg.org/a-j-wood/pv/issues/105) for
|
||||
full details.
|
||||
|
||||
The "**\--remote**" option requires that either */run/user/\<uid\>/* or
|
||||
*\$HOME/* can be written to, for inter-process communication.
|
||||
|
||||
The "**\--size**" option has no effect if used with
|
||||
"**\--watchfd** *PID*" to watch all file descriptors of a process, but
|
||||
will work with "**\--watchfd** *PID*:*FD*" to watch a single file
|
||||
descriptor.
|
||||
|
||||
If the input size cannot be calculated, and the output is a block
|
||||
device, then **pv** will read the output device\'s size, use that as if
|
||||
it had been passed to "**\--size**", and activate "**\--stop-at-size**".
|
||||
|
||||
# REPORTING BUGS
|
||||
|
||||
Please report any bugs to **pv@ivarch.com**.
|
||||
|
||||
Alternatively, use the issue tracker linked from the **pv** home page:
|
||||
\<https://www.ivarch.com/programs/pv.shtml\>
|
||||
Alternatively, use the issue tracker linked from the [**pv** home
|
||||
page](https://www.ivarch.com/programs/pv.shtml).
|
||||
|
||||
# SEE ALSO
|
||||
|
||||
**cat**(1), **dialog**(1), **splice**(2), **open**(2) (for **O_DIRECT**)
|
||||
**cat**(1), **dialog**(1), **splice**(2), **fdatasync**(2), **open**(2)
|
||||
(for **O_DIRECT**)
|
||||
|
||||
# COPYRIGHT
|
||||
|
||||
Copyright © 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood.
|
||||
Copyright © 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2024 Andrew
|
||||
Wood.
|
||||
|
||||
License GPLv3+: GNU GPL version 3 or later
|
||||
\<https://www.gnu.org/licenses/gpl-3.0.html\>.
|
||||
License GPLv3+: [GNU GPL version 3 or
|
||||
later](https://www.gnu.org/licenses/gpl-3.0.html).
|
||||
|
||||
This is free software: you are free to change and redistribute it. There
|
||||
is NO WARRANTY, to the extent permitted by law.
|
||||
|
||||
Please see the package\'s ACKNOWLEDGEMENTS file for a complete list of
|
||||
contributors.
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
cs
|
||||
de
|
||||
es
|
||||
fr
|
||||
pl
|
||||
pt
|
||||
ru
|
||||
tr
|
||||
|
||||
@@ -4,11 +4,14 @@ src/main/main.c
|
||||
src/main/options.c
|
||||
src/main/remote.c
|
||||
src/main/version.c
|
||||
src/pv/calc.c
|
||||
src/pv/cursor.c
|
||||
src/pv/display.c
|
||||
src/pv/elapsedtime.c
|
||||
src/pv/file.c
|
||||
src/pv/loop.c
|
||||
src/pv/number.c
|
||||
src/pv/proctitle.c
|
||||
src/pv/signal.c
|
||||
src/pv/state.c
|
||||
src/pv/string.c
|
||||
|
||||
@@ -0,0 +1,543 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Report-Msgid-Bugs-To: pv@ivarch.com\n"
|
||||
"POT-Creation-Date: 2024-12-02 17:56+0000\n"
|
||||
"PO-Revision-Date: 2024-10-13 20:43+0000\n"
|
||||
"Last-Translator: mmatous <mmatous@users.noreply.translate.codeberg.org>\n"
|
||||
"Language-Team: Czech <https://translate.codeberg.org/projects/pv/pv/cs/>\n"
|
||||
"Language: cs\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
|
||||
"X-Generator: Weblate 5.7.2\n"
|
||||
|
||||
#: src/main/help.c:284
|
||||
msgid "show progress bar"
|
||||
msgstr "ukaž indikátor průběhu"
|
||||
|
||||
#: src/main/help.c:287
|
||||
msgid "show elapsed time"
|
||||
msgstr "ukaž uběhlý čas"
|
||||
|
||||
#: src/main/help.c:290
|
||||
msgid "show estimated time of arrival (completion)"
|
||||
msgstr "ukaž přibližný zbývající čas"
|
||||
|
||||
#: src/main/help.c:293
|
||||
msgid "show absolute estimated time of arrival (completion)"
|
||||
msgstr "ukaž přibližný čas dokončení"
|
||||
|
||||
#: src/main/help.c:296
|
||||
msgid "show data transfer rate counter"
|
||||
msgstr "ukaž okamžitou rychlost přenosu dat"
|
||||
|
||||
#: src/main/help.c:299
|
||||
msgid "show data transfer average rate counter"
|
||||
msgstr "ukaž průměrnou rychlost přenosu dat"
|
||||
|
||||
#: src/main/help.c:302
|
||||
msgid "show number of bytes transferred"
|
||||
msgstr "ukaž počet přenesených bajtů"
|
||||
|
||||
#: src/main/help.c:305
|
||||
msgid "show percentage of transfer buffer in use"
|
||||
msgstr "ukaž procento využité vyrovnávací paměti"
|
||||
|
||||
#: src/main/help.c:307
|
||||
msgid "NUM"
|
||||
msgstr "ČÍS"
|
||||
|
||||
#: src/main/help.c:308
|
||||
msgid "show NUM bytes last written"
|
||||
msgstr "zobraz ČÍS posledních zapsaných bajtů"
|
||||
|
||||
#: src/main/help.c:310
|
||||
msgid "FORMAT"
|
||||
msgstr "FORMÁT"
|
||||
|
||||
#: src/main/help.c:311
|
||||
msgid "set output format to FORMAT"
|
||||
msgstr "nastav formát výstupu na FORMÁT"
|
||||
|
||||
#: src/main/help.c:314
|
||||
msgid "output percentages, not visual information"
|
||||
msgstr "vypisuj procenta, ne vizuální informace"
|
||||
|
||||
#: src/main/help.c:317
|
||||
msgid "do not output any transfer information at all"
|
||||
msgstr "nevypisuj žádné informace o přenosu"
|
||||
|
||||
#: src/main/help.c:321
|
||||
msgid "show number of bits transferred"
|
||||
msgstr "ukaž počet přenesených bitů"
|
||||
|
||||
#: src/main/help.c:324
|
||||
msgid "treat suffixes as multiples of 1000 rather than 1024"
|
||||
msgstr "zacházej se suffixy jako s násobky 1000 namísto 1024"
|
||||
|
||||
#: src/main/help.c:327
|
||||
msgid "display nothing until first byte transferred"
|
||||
msgstr "nic nevypisuj, dokud není přenesen první byte"
|
||||
|
||||
#: src/main/help.c:329 src/main/help.c:344 src/main/help.c:347
|
||||
msgid "SEC"
|
||||
msgstr "SEK"
|
||||
|
||||
#: src/main/help.c:330
|
||||
msgid "display nothing until SEC seconds have passed"
|
||||
msgstr "nic nevypisuj, dokud neuplyne SEK sekund"
|
||||
|
||||
#: src/main/help.c:332
|
||||
msgid "SIZE"
|
||||
msgstr "VEL"
|
||||
|
||||
#: src/main/help.c:333
|
||||
msgid "set estimated data size to SIZE bytes"
|
||||
msgstr "nastav očekávanou velikost dat na VEL bajtů"
|
||||
|
||||
#: src/main/help.c:336
|
||||
msgid "if size unknown, show rate vs max rate"
|
||||
msgstr "pokud je velikost neznámá, ukaž rychlost vs maximální rychlost"
|
||||
|
||||
#: src/main/help.c:339
|
||||
msgid "count lines instead of bytes"
|
||||
msgstr "počítej řádky místo bajtů"
|
||||
|
||||
#: src/main/help.c:342
|
||||
msgid "lines are null-terminated"
|
||||
msgstr "řádky jsou zakončené nulovým znakem"
|
||||
|
||||
#: src/main/help.c:345
|
||||
msgid "update every SEC seconds"
|
||||
msgstr "aktualizuj každých SEK sekund"
|
||||
|
||||
#: src/main/help.c:348
|
||||
msgid "compute average rate over past SEC seconds (default 30s)"
|
||||
msgstr "počítej průměrnou rychlost za posledních SEK sekund (výchozí: 30)"
|
||||
|
||||
#: src/main/help.c:350
|
||||
msgid "WIDTH"
|
||||
msgstr "ŠÍŘ"
|
||||
|
||||
#: src/main/help.c:351
|
||||
msgid "assume terminal is WIDTH characters wide"
|
||||
msgstr "předpokládej šířku terminálu ŠÍŘ znaků"
|
||||
|
||||
#: src/main/help.c:353
|
||||
msgid "HEIGHT"
|
||||
msgstr "VÝŠ"
|
||||
|
||||
#: src/main/help.c:354
|
||||
msgid "assume terminal is HEIGHT rows high"
|
||||
msgstr "předpokládej výšku terminálu VÝŠ znaků"
|
||||
|
||||
#: src/main/help.c:356
|
||||
msgid "NAME"
|
||||
msgstr "JMÉNO"
|
||||
|
||||
#: src/main/help.c:357
|
||||
msgid "prefix visual information with NAME"
|
||||
msgstr "přidej JMÉNO před vizuální informace"
|
||||
|
||||
#: src/main/help.c:359
|
||||
msgid "SPEC"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:360
|
||||
msgid "also send progress to SPEC"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:363
|
||||
msgid "output transfer statistics at the end"
|
||||
msgstr "po dokončení vypiš údaje o přenosu"
|
||||
|
||||
#: src/main/help.c:366
|
||||
msgid "output even if standard error is not a terminal"
|
||||
msgstr "vypisuj výstup i pokud standardní chybový výstup není terminál"
|
||||
|
||||
#: src/main/help.c:369
|
||||
msgid "use cursor positioning escape sequences"
|
||||
msgstr "pozicuj kurzor pomocí řídících znaků"
|
||||
|
||||
#: src/main/help.c:372 src/main/help.c:402 src/main/help.c:414
|
||||
#: src/main/help.c:424
|
||||
msgid "FILE"
|
||||
msgstr "SOUBOR"
|
||||
|
||||
#: src/main/help.c:373
|
||||
msgid "write output to FILE instead of stdout"
|
||||
msgstr "zapiš výstup do SOUBORu namísto standardního výstupu"
|
||||
|
||||
#: src/main/help.c:375
|
||||
msgid "RATE"
|
||||
msgstr "RYCH"
|
||||
|
||||
#: src/main/help.c:376
|
||||
msgid "limit transfer to RATE bytes per second"
|
||||
msgstr "omez přenosovou rychlost na RYCH bajtů za sekundu"
|
||||
|
||||
#: src/main/help.c:378 src/main/help.c:387
|
||||
msgid "BYTES"
|
||||
msgstr "BAJT"
|
||||
|
||||
#: src/main/help.c:379
|
||||
msgid "use a buffer size of BYTES"
|
||||
msgstr "použij vyrovnávací pamět BAJT bajtů"
|
||||
|
||||
#: src/main/help.c:382
|
||||
msgid "never use splice(), always use read/write"
|
||||
msgstr "nepoužívej splice(), vždy použij read/write"
|
||||
|
||||
#: src/main/help.c:385
|
||||
msgid "skip read errors in input"
|
||||
msgstr "ignoruj chyby při čtení vstupu"
|
||||
|
||||
#: src/main/help.c:388
|
||||
msgid "skip errors in BYTES blocks at a time"
|
||||
msgstr "přeskakuj chyby v blocích BAJTů naráz"
|
||||
|
||||
#: src/main/help.c:391
|
||||
msgid "stop after --size bytes have been transferred"
|
||||
msgstr "zastav po přenosu --size bajtů"
|
||||
|
||||
#: src/main/help.c:394
|
||||
msgid "flush cache to disk after every write"
|
||||
msgstr "po každém zápisu vyprázdni cache na disk"
|
||||
|
||||
#: src/main/help.c:397
|
||||
msgid "use direct I/O to bypass cache"
|
||||
msgstr "použij přímý V/V k obejítí cache"
|
||||
|
||||
#: src/main/help.c:400
|
||||
msgid "discard input instead of writing to output"
|
||||
msgstr "zahoď vstup namísto zápisu na výstup"
|
||||
|
||||
#: src/main/help.c:403
|
||||
msgid "write all input to FILE before writing to output"
|
||||
msgstr "zapiš veškerý vstup do SOUBORu před výpisem na výstup"
|
||||
|
||||
#: src/main/help.c:405
|
||||
msgid "PID[:FD]"
|
||||
msgstr "PID[:DS]"
|
||||
|
||||
#: src/main/help.c:406
|
||||
msgid "watch file FD opened by process PID"
|
||||
msgstr "sleduj soubor DS otevřený procesem PID"
|
||||
|
||||
#: src/main/help.c:409
|
||||
msgid "PID"
|
||||
msgstr "PID"
|
||||
|
||||
#: src/main/help.c:410
|
||||
msgid "update settings of process PID"
|
||||
msgstr "aktualizuj nastavení procesu PID"
|
||||
|
||||
#: src/main/help.c:415
|
||||
msgid "save process ID in FILE"
|
||||
msgstr "ulož id procesu do SOUBORu"
|
||||
|
||||
#: src/main/help.c:418
|
||||
msgid "show this help and exit"
|
||||
msgstr "ukaž pomoc a skonči"
|
||||
|
||||
#: src/main/help.c:421
|
||||
msgid "show version information and exit"
|
||||
msgstr "ukaž informace o verzi a skonči"
|
||||
|
||||
#: src/main/help.c:425
|
||||
msgid "write debug logs to FILE"
|
||||
msgstr "zapiš ladící záznamy do SOUBORu"
|
||||
|
||||
#: src/main/help.c:450
|
||||
#, c-format
|
||||
msgid "Usage: %s [OPTION] [FILE]..."
|
||||
msgstr "Použití: %s [VOLBY] [SOUBOR]..."
|
||||
|
||||
#: src/main/help.c:461
|
||||
msgid ""
|
||||
"Concatenate FILE(s), or standard input, to standard output, with monitoring."
|
||||
msgstr ""
|
||||
"Spoj SOUBOR(y) nebo standardní vstup na standardního výstup, s monitoringem."
|
||||
|
||||
#: src/main/help.c:598
|
||||
#, c-format
|
||||
msgid "Please report any bugs to: %s"
|
||||
msgstr "Prosím, hlašte veškeré chyby na: %s"
|
||||
|
||||
#: src/main/main.c:230
|
||||
msgid "(input)"
|
||||
msgstr "(vstup)"
|
||||
|
||||
#: src/main/main.c:319
|
||||
msgid "state allocation failed"
|
||||
msgstr "selhala alokace stavu"
|
||||
|
||||
#: src/main/options.c:144 src/pv/file.c:324
|
||||
msgid "failed to stat file"
|
||||
msgstr "nebylo možné zjistit informace o souboru"
|
||||
|
||||
#: src/main/options.c:158
|
||||
msgid "is a directory"
|
||||
msgstr "je adresář"
|
||||
|
||||
#: src/main/options.c:187
|
||||
msgid "failed to generate sysfs filename"
|
||||
msgstr "selhalo vytváření jména pro soubor v sysfs"
|
||||
|
||||
#: src/main/options.c:209
|
||||
msgid "failed to read sysfs size file"
|
||||
msgstr "selhalo čtení velikosti souboru v sysfs"
|
||||
|
||||
#: src/main/options.c:229
|
||||
msgid "failed to open block device"
|
||||
msgstr "selhalo otevření blokového zařízení"
|
||||
|
||||
#: src/main/options.c:239
|
||||
msgid "failed to determine size of block device"
|
||||
msgstr "selhalo zjištění velikosti blokového zařízení"
|
||||
|
||||
#: src/main/options.c:344
|
||||
msgid "option structure allocation failed"
|
||||
msgstr "selhala alokace struktury pro volby"
|
||||
|
||||
#: src/main/options.c:363
|
||||
msgid "option structure argv allocation failed"
|
||||
msgstr "selhala alokace struktury pro argv"
|
||||
|
||||
#: src/main/options.c:425
|
||||
msgid "integer argument expected"
|
||||
msgstr "očekáván celočíselný argument"
|
||||
|
||||
#: src/main/options.c:436
|
||||
msgid "numeric argument expected"
|
||||
msgstr "očekáván číselný argument"
|
||||
|
||||
#: src/main/options.c:447
|
||||
msgid "process ID or pid:fd pair expected"
|
||||
msgstr "očekáváno ID procesu nebo dvojice PID:DS"
|
||||
|
||||
#: src/main/options.c:454
|
||||
msgid "invalid process ID"
|
||||
msgstr "neplatné ID procesu"
|
||||
|
||||
#: src/main/options.c:679
|
||||
#, c-format
|
||||
msgid "Try `%s --help' for more information."
|
||||
msgstr "Zkuste `%s --help' pro více informací."
|
||||
|
||||
#: src/main/options.c:681
|
||||
#, c-format
|
||||
msgid "Try `%s -h' for more information."
|
||||
msgstr "Zkuste `%s --h' pro více informací."
|
||||
|
||||
#: src/main/options.c:712
|
||||
msgid ""
|
||||
"cannot use line mode or transfer modifier options when watching file "
|
||||
"descriptors"
|
||||
msgstr ""
|
||||
"při sledování deskriptorů souborů nelze použít řádkový mód nebo volby pro "
|
||||
"modifikaci přenosu"
|
||||
|
||||
#: src/main/options.c:721
|
||||
msgid "cannot use cursor positioning when watching file descriptors"
|
||||
msgstr "při sledování deskriptorů souborů nelze pozicování kurzoru použít"
|
||||
|
||||
#: src/main/options.c:730
|
||||
msgid "cannot use remote control when watching file descriptors"
|
||||
msgstr "při sledování deskriptorů souborů nelze použít vzdálené ovládání"
|
||||
|
||||
#: src/main/options.c:739
|
||||
msgid "cannot transfer files when watching file descriptors"
|
||||
msgstr "při sledování deskriptorů souborů nelze použít přenos souborů"
|
||||
|
||||
#: src/main/options.c:754
|
||||
msgid "not available on systems without /proc/self/fdinfo"
|
||||
msgstr "není dostupné na systémech bez /proc/self/fdinfo"
|
||||
|
||||
#: src/main/remote.c:304
|
||||
msgid "message not received"
|
||||
msgstr "zpráva nepřijata"
|
||||
|
||||
#: src/main/remote.c:431
|
||||
msgid "SA_SIGINFO not supported on this system"
|
||||
msgstr "SA_SIGINFO není na tomto systému podporováno"
|
||||
|
||||
#: src/main/version.c:28
|
||||
msgid "License: GPLv3+ <https://www.gnu.org/licenses/gpl-3.0.html>"
|
||||
msgstr "Licence: GPLv3+ <https://jxself.org/translations/gpl-3.cz.shtml>"
|
||||
|
||||
#: src/main/version.c:29
|
||||
msgid "This is free software: you are free to change and redistribute it."
|
||||
msgstr "Toto je svobodný software; můžete ho volně měnit a šířit."
|
||||
|
||||
#: src/main/version.c:30
|
||||
msgid "There is NO WARRANTY, to the extent permitted by law."
|
||||
msgstr "Na program se nevztahuje ŽÁDNÁ ZÁRUKA, v míře povolené zákonem."
|
||||
|
||||
#: src/main/version.c:32
|
||||
msgid "Project web site"
|
||||
msgstr "Stránka projektu"
|
||||
|
||||
#: src/pv/cursor.c:61
|
||||
msgid "failed to get terminal name"
|
||||
msgstr "selhalo zjištění názvu terminálu"
|
||||
|
||||
#: src/pv/cursor.c:106
|
||||
msgid "failed to open lock file"
|
||||
msgstr "selhalo otevření zámkového souboru"
|
||||
|
||||
#: src/pv/cursor.c:139
|
||||
msgid "lock attempt failed"
|
||||
msgstr "selhal pokus o uzamčení"
|
||||
|
||||
#: src/pv/cursor.c:400
|
||||
msgid "failed to open terminal"
|
||||
msgstr "selhalo otevření terminálu"
|
||||
|
||||
#: src/pv/display.c:233
|
||||
msgid "yzafpnum kMGTPEZY"
|
||||
msgstr "yzafpnum kMGTPEZY"
|
||||
|
||||
#: src/pv/display.c:251
|
||||
msgid "yzafpnum KMGTPEZY"
|
||||
msgstr "yzafpnum KMGTPEZY"
|
||||
|
||||
#: src/pv/display.c:681 src/pv/transfer.c:1011
|
||||
msgid "buffer allocation failed"
|
||||
msgstr "selhala alokace vyrovnávací paměti"
|
||||
|
||||
#: src/pv/display.c:810
|
||||
msgid "b"
|
||||
msgstr "b"
|
||||
|
||||
#: src/pv/display.c:813 src/pv/transfer.c:602
|
||||
msgid "B"
|
||||
msgstr "B"
|
||||
|
||||
#: src/pv/display.c:857 src/pv/display.c:872 src/pv/display.c:1091
|
||||
#: src/pv/loop.c:549
|
||||
msgid "b/s"
|
||||
msgstr "b/s"
|
||||
|
||||
#: src/pv/display.c:861 src/pv/display.c:876 src/pv/display.c:1095
|
||||
msgid "/s"
|
||||
msgstr "/s"
|
||||
|
||||
#: src/pv/display.c:861 src/pv/display.c:876 src/pv/display.c:1095
|
||||
#: src/pv/loop.c:549
|
||||
msgid "B/s"
|
||||
msgstr "B/s"
|
||||
|
||||
#: src/pv/display.c:904 src/pv/display.c:908
|
||||
msgid "ETA"
|
||||
msgstr "ETA"
|
||||
|
||||
#: src/pv/display.c:974
|
||||
msgid "FIN"
|
||||
msgstr "FIN"
|
||||
|
||||
#: src/pv/file.c:149
|
||||
msgid "failed to seek to start of output"
|
||||
msgstr "selhalo posunutí za začátek výstupu"
|
||||
|
||||
#: src/pv/file.c:294
|
||||
msgid "failed to close file"
|
||||
msgstr "selhalo zavření souboru"
|
||||
|
||||
#: src/pv/file.c:317
|
||||
msgid "failed to read file"
|
||||
msgstr "selhalo čtení ze souboru"
|
||||
|
||||
#: src/pv/file.c:332
|
||||
msgid "failed to stat output file"
|
||||
msgstr "selhalo zjištění informací o výstupním souboru"
|
||||
|
||||
#: src/pv/file.c:354
|
||||
msgid "input file is output file"
|
||||
msgstr "vstupní soubor je výstupní soubor"
|
||||
|
||||
#: src/pv/file.c:412
|
||||
msgid "(none)"
|
||||
msgstr "(žádný)"
|
||||
|
||||
#: src/pv/file.c:414
|
||||
msgid "(stdin)"
|
||||
msgstr "(stdin)"
|
||||
|
||||
#: src/pv/loop.c:548
|
||||
msgid "rate min/avg/max/mdev"
|
||||
msgstr "rychlost min/avg/max/std"
|
||||
|
||||
#: src/pv/loop.c:560
|
||||
msgid "rate not measured"
|
||||
msgstr "rychlost neměřena"
|
||||
|
||||
#: src/pv/loop.c:767 src/pv/loop.c:818 src/pv/loop.c:859 src/pv/watchpid.c:99
|
||||
#: src/pv/watchpid.c:109 src/pv/watchpid.c:120 src/pv/watchpid.c:128
|
||||
#: src/pv/watchpid.c:165 src/pv/watchpid.c:184 src/pv/watchpid.c:192
|
||||
#: src/pv/watchpid.c:202 src/pv/watchpid.c:300 src/pv/watchpid.c:308
|
||||
#: src/pv/watchpid.c:384 src/pv/watchpid.c:405
|
||||
msgid "pid"
|
||||
msgstr "pid"
|
||||
|
||||
#: src/pv/state.c:40
|
||||
msgid "history structure allocation failed"
|
||||
msgstr "selhala alokace struktury historie"
|
||||
|
||||
#: src/pv/state.c:572 src/pv/state.c:583
|
||||
msgid "file list allocation failed"
|
||||
msgstr "selhala alokace seznamu souborů"
|
||||
|
||||
#: src/pv/transfer.c:464
|
||||
msgid "read failed"
|
||||
msgstr "čtení selhalo"
|
||||
|
||||
#: src/pv/transfer.c:487
|
||||
msgid "warning: read errors detected"
|
||||
msgstr "varování: detekovány chyby při čtení"
|
||||
|
||||
#: src/pv/transfer.c:503
|
||||
msgid "file is not seekable"
|
||||
msgstr "souborem nelze procházet"
|
||||
|
||||
#: src/pv/transfer.c:581
|
||||
msgid "failed to seek past error"
|
||||
msgstr "selhal skok za chybu"
|
||||
|
||||
#: src/pv/transfer.c:601
|
||||
msgid "skipped past read error"
|
||||
msgstr "chyba přeskočena"
|
||||
|
||||
#: src/pv/transfer.c:642
|
||||
msgid "no transfer buffer allocated"
|
||||
msgstr "vyrovnávací paměť není alokována"
|
||||
|
||||
#: src/pv/transfer.c:684
|
||||
msgid "failed to set interval timer"
|
||||
msgstr "selhalo nastavení intervalového časovače"
|
||||
|
||||
#: src/pv/transfer.c:710
|
||||
msgid "failed to clear interval timer"
|
||||
msgstr "selhalo vynulování intervalového časovače"
|
||||
|
||||
#: src/pv/transfer.c:740
|
||||
msgid "line position buffer allocation failed"
|
||||
msgstr "selhala alokace vyrovnávací paměti pro pozici v řádcích"
|
||||
|
||||
#: src/pv/transfer.c:872
|
||||
msgid "write failed"
|
||||
msgstr "zápis selhal"
|
||||
|
||||
#: src/pv/transfer.c:1109
|
||||
msgid "select call failed"
|
||||
msgstr "selhalo volání select"
|
||||
|
||||
#: src/pv/watchpid.c:109 src/pv/watchpid.c:121 src/pv/watchpid.c:130
|
||||
#: src/pv/watchpid.c:184 src/pv/watchpid.c:193 src/pv/watchpid.c:204
|
||||
msgid "fd"
|
||||
msgstr "ds"
|
||||
|
||||
#: src/pv/watchpid.c:130 src/pv/watchpid.c:204
|
||||
msgid "not a regular file or block device"
|
||||
msgstr "není obyčejný soubor nebo blokové zařízení"
|
||||
@@ -1,9 +1,15 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Report-Msgid-Bugs-To: pv@ivarch.com\n"
|
||||
"POT-Creation-Date: 2023-11-19 14:19+0000\n"
|
||||
"POT-Creation-Date: 2024-12-02 17:56+0000\n"
|
||||
"PO-Revision-Date: 2024-10-13 20:43+0000\n"
|
||||
"Last-Translator: fnetX <otto@codeberg.org>\n"
|
||||
"Language-Team: German <https://translate.codeberg.org/projects/pv/pv/de/>\n"
|
||||
"Language: de\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 5.7.2\n"
|
||||
"Date: 1999-06-01 15:18:29+0100\n"
|
||||
"From: Andrew Wood <ivarch@ubik>\n"
|
||||
"Xgettext-Options: --default-domain=pkgbuild --directory=./.pkgdir --add-"
|
||||
@@ -42,441 +48,520 @@ msgstr "zeige die Datentransferrate an"
|
||||
|
||||
#: src/main/help.c:299
|
||||
msgid "show data transfer average rate counter"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:301 src/main/help.c:329 src/main/help.c:341
|
||||
msgid "SEC"
|
||||
msgstr ""
|
||||
msgstr "zeige die durchschnittliche Übertragungsrate"
|
||||
|
||||
#: src/main/help.c:302
|
||||
msgid "compute average rate over past SEC seconds (default 30s)"
|
||||
msgstr ""
|
||||
msgid "show number of bytes transferred"
|
||||
msgstr "zeige die Anzahl der übertragenen Bytes"
|
||||
|
||||
#: src/main/help.c:305
|
||||
msgid "show number of bytes transferred"
|
||||
msgstr "zeige die Anzahl von Bytes, die transferiert worden sind"
|
||||
|
||||
#: src/main/help.c:308
|
||||
msgid "show number of bits transferred"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:311
|
||||
msgid "show percentage of transfer buffer in use"
|
||||
msgstr "zeige, wie viel Prozent des Übertragungsbuffers in Benutzung sind"
|
||||
|
||||
#: src/main/help.c:313
|
||||
#: src/main/help.c:307
|
||||
msgid "NUM"
|
||||
msgstr ""
|
||||
msgstr "NUM"
|
||||
|
||||
#: src/main/help.c:314
|
||||
#: src/main/help.c:308
|
||||
msgid "show NUM bytes last written"
|
||||
msgstr "NUM zeige die zuletzt geschriebenen NUM Bytes"
|
||||
|
||||
#: src/main/help.c:316
|
||||
#: src/main/help.c:310
|
||||
msgid "FORMAT"
|
||||
msgstr ""
|
||||
msgstr "FORMAT"
|
||||
|
||||
#: src/main/help.c:317
|
||||
#: src/main/help.c:311
|
||||
msgid "set output format to FORMAT"
|
||||
msgstr "setze das Ausgabeformat auf FORMAT"
|
||||
|
||||
#: src/main/help.c:320
|
||||
#: src/main/help.c:314
|
||||
msgid "output percentages, not visual information"
|
||||
msgstr "Ausgabe von Prozent-Angaben statt visueller Darstellung"
|
||||
|
||||
#: src/main/help.c:323
|
||||
#: src/main/help.c:317
|
||||
msgid "do not output any transfer information at all"
|
||||
msgstr "sämtliche Transferinformationen unterdrücken"
|
||||
|
||||
#: src/main/help.c:321
|
||||
msgid "show number of bits transferred"
|
||||
msgstr "zeige die Anzahl der übertragenen Bits"
|
||||
|
||||
#: src/main/help.c:324
|
||||
msgid "treat suffixes as multiples of 1000 rather than 1024"
|
||||
msgstr "behandle Endungen als Vielfache von 1000 statt von 1024"
|
||||
|
||||
#: src/main/help.c:327
|
||||
msgid "display nothing until first byte transferred"
|
||||
msgstr "keine Ausgabe bevor das erste Byte übertragen wurde"
|
||||
|
||||
#: src/main/help.c:329 src/main/help.c:344 src/main/help.c:347
|
||||
msgid "SEC"
|
||||
msgstr "SEK"
|
||||
|
||||
#: src/main/help.c:330
|
||||
msgid "display nothing until SEC seconds have passed"
|
||||
msgstr "SEC nichts anzeigen, bis SEC Sekunden vergangen sind"
|
||||
msgstr "nichts anzeigen ehe SEK Sekunden vergangen sind"
|
||||
|
||||
#: src/main/help.c:332
|
||||
msgid "SIZE"
|
||||
msgstr ""
|
||||
msgstr "GRÖẞE"
|
||||
|
||||
#: src/main/help.c:333
|
||||
msgid "set estimated data size to SIZE bytes"
|
||||
msgstr "setze erwartete Datenlänge auf SIZE Byte"
|
||||
|
||||
#: src/main/help.c:336
|
||||
msgid "if size unknown, show rate vs max rate"
|
||||
msgstr "zeige Rate vs maximale Rate, falls die größe unbekannt ist"
|
||||
|
||||
#: src/main/help.c:339
|
||||
msgid "count lines instead of bytes"
|
||||
msgstr "zähle Zeilen anstelle von Bytes"
|
||||
|
||||
#: src/main/help.c:339
|
||||
#: src/main/help.c:342
|
||||
msgid "lines are null-terminated"
|
||||
msgstr "Zeilen sind nullterminiert"
|
||||
|
||||
#: src/main/help.c:342
|
||||
msgid "update every SEC seconds"
|
||||
msgstr "aktualisiere Ausgabe nach SEC Sekunden Intervall"
|
||||
|
||||
#: src/main/help.c:344
|
||||
msgid "WIDTH"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:345
|
||||
msgid "assume terminal is WIDTH characters wide"
|
||||
msgstr "setze Terminal-Breite auf WIDTH Zeichen"
|
||||
|
||||
#: src/main/help.c:347
|
||||
msgid "HEIGHT"
|
||||
msgstr ""
|
||||
msgid "update every SEC seconds"
|
||||
msgstr "aktualisiere Ausgabe nach SEK Sekunden Intervall"
|
||||
|
||||
#: src/main/help.c:348
|
||||
msgid "assume terminal is HEIGHT rows high"
|
||||
msgstr "setze Terminal-Höhe auf HEIGHT Zeichen"
|
||||
msgid "compute average rate over past SEC seconds (default 30s)"
|
||||
msgstr ""
|
||||
"berechne die durchschnittliche Übertragungsrate über die letzten SEK "
|
||||
"Sekunden (Standard 30s)"
|
||||
|
||||
#: src/main/help.c:350
|
||||
msgid "NAME"
|
||||
msgstr ""
|
||||
msgid "WIDTH"
|
||||
msgstr "BREITE"
|
||||
|
||||
#: src/main/help.c:351
|
||||
msgid "assume terminal is WIDTH characters wide"
|
||||
msgstr "setze Terminal-Breite auf BREITE Zeichen"
|
||||
|
||||
#: src/main/help.c:353
|
||||
msgid "HEIGHT"
|
||||
msgstr "HÖHE"
|
||||
|
||||
#: src/main/help.c:354
|
||||
msgid "assume terminal is HEIGHT rows high"
|
||||
msgstr "setze Terminal-Höhe auf HÖHE Zeichen"
|
||||
|
||||
#: src/main/help.c:356
|
||||
msgid "NAME"
|
||||
msgstr "NAME"
|
||||
|
||||
#: src/main/help.c:357
|
||||
msgid "prefix visual information with NAME"
|
||||
msgstr "setze den NAMEn für visuelle Darstellung"
|
||||
|
||||
#: src/main/help.c:354
|
||||
#: src/main/help.c:359
|
||||
msgid "SPEC"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:360
|
||||
msgid "also send progress to SPEC"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:363
|
||||
msgid "output transfer statistics at the end"
|
||||
msgstr "Übertragungsstatistiken am Ende ausgeben"
|
||||
|
||||
#: src/main/help.c:366
|
||||
msgid "output even if standard error is not a terminal"
|
||||
msgstr ""
|
||||
"Ausgabe auch dann erzwingen, wenn der Fehlerausgabe-Kanal kein Terminal ist"
|
||||
|
||||
#: src/main/help.c:357
|
||||
#: src/main/help.c:369
|
||||
msgid "use cursor positioning escape sequences"
|
||||
msgstr "benutze Escape-Sequenzen zur Cursor-Positionierung"
|
||||
|
||||
#: src/main/help.c:360
|
||||
msgid "RATE"
|
||||
msgstr ""
|
||||
#: src/main/help.c:372 src/main/help.c:402 src/main/help.c:414
|
||||
#: src/main/help.c:424
|
||||
msgid "FILE"
|
||||
msgstr "DATEI"
|
||||
|
||||
#: src/main/help.c:361
|
||||
#: src/main/help.c:373
|
||||
msgid "write output to FILE instead of stdout"
|
||||
msgstr "schreibe die Ausgabe in DATEI statt in die Standardausgabe"
|
||||
|
||||
#: src/main/help.c:375
|
||||
msgid "RATE"
|
||||
msgstr "RATE"
|
||||
|
||||
#: src/main/help.c:376
|
||||
msgid "limit transfer to RATE bytes per second"
|
||||
msgstr "beschränke die Transferrate auf RATE Byte pro Sekunde"
|
||||
|
||||
#: src/main/help.c:363 src/main/help.c:372
|
||||
#: src/main/help.c:378 src/main/help.c:387
|
||||
msgid "BYTES"
|
||||
msgstr ""
|
||||
msgstr "BYTES"
|
||||
|
||||
#: src/main/help.c:364
|
||||
#: src/main/help.c:379
|
||||
msgid "use a buffer size of BYTES"
|
||||
msgstr "BYTES benutze einen Puffer in der Größe von BYTES"
|
||||
msgstr "benutze einen Puffer in der Größe von BYTES"
|
||||
|
||||
#: src/main/help.c:367
|
||||
#: src/main/help.c:382
|
||||
msgid "never use splice(), always use read/write"
|
||||
msgstr "anstelle von splice() immer read/write benutzen"
|
||||
|
||||
#: src/main/help.c:370
|
||||
#: src/main/help.c:385
|
||||
msgid "skip read errors in input"
|
||||
msgstr "Lesefehler in der Eingabe nicht beachten"
|
||||
|
||||
#: src/main/help.c:373
|
||||
#: src/main/help.c:388
|
||||
msgid "skip errors in BYTES blocks at a time"
|
||||
msgstr ""
|
||||
msgstr "bei Fehlern BYTES am Stück überspringen"
|
||||
|
||||
#: src/main/help.c:376
|
||||
#: src/main/help.c:391
|
||||
msgid "stop after --size bytes have been transferred"
|
||||
msgstr "anhalten, nachdem --size Bytes übertragen wurden"
|
||||
|
||||
#: src/main/help.c:379
|
||||
msgid "flush cache to disk after every write"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:382
|
||||
msgid "use direct I/O to bypass cache"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:385
|
||||
msgid "discard input instead of writing to output"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:388
|
||||
msgid "PID"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:389
|
||||
msgid "update settings of process PID"
|
||||
msgstr "Einstellungen der Prozess-PID updaten"
|
||||
|
||||
#: src/main/help.c:393 src/main/help.c:408
|
||||
msgid "FILE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:394
|
||||
msgid "save process ID in FILE"
|
||||
msgstr "Prozess-ID in FILE speichern"
|
||||
msgid "flush cache to disk after every write"
|
||||
msgstr "schreibe den Cache nach jedem Schreibvorgang auf die Festplatte"
|
||||
|
||||
#: src/main/help.c:397
|
||||
msgid "PID[:FD]"
|
||||
msgstr ""
|
||||
msgid "use direct I/O to bypass cache"
|
||||
msgstr "verwende direkte E/A, um den Cache zu umgehen"
|
||||
|
||||
#: src/main/help.c:398
|
||||
#: src/main/help.c:400
|
||||
msgid "discard input instead of writing to output"
|
||||
msgstr "verwirf die Eingabe anstatt in die Ausgabe zu schreiben"
|
||||
|
||||
#: src/main/help.c:403
|
||||
msgid "write all input to FILE before writing to output"
|
||||
msgstr "Ausgabe nach FILE schrieben bevor sie ausgegeben wird"
|
||||
|
||||
#: src/main/help.c:405
|
||||
msgid "PID[:FD]"
|
||||
msgstr "PID[:FD]"
|
||||
|
||||
#: src/main/help.c:406
|
||||
msgid "watch file FD opened by process PID"
|
||||
msgstr "die vom Prozess PID geöffnete Datei FD beobachten"
|
||||
|
||||
#: src/main/help.c:402
|
||||
#: src/main/help.c:409
|
||||
msgid "PID"
|
||||
msgstr "PID"
|
||||
|
||||
#: src/main/help.c:410
|
||||
msgid "update settings of process PID"
|
||||
msgstr "Einstellungen der Prozess-PID updaten"
|
||||
|
||||
#: src/main/help.c:415
|
||||
msgid "save process ID in FILE"
|
||||
msgstr "Prozess-ID in DATEI speichern"
|
||||
|
||||
#: src/main/help.c:418
|
||||
msgid "show this help and exit"
|
||||
msgstr "zeige diese Hilfe und beende"
|
||||
|
||||
#: src/main/help.c:405
|
||||
#: src/main/help.c:421
|
||||
msgid "show version information and exit"
|
||||
msgstr "zeige Versionsinformationen und beende"
|
||||
|
||||
#: src/main/help.c:409
|
||||
#: src/main/help.c:425
|
||||
msgid "write debug logs to FILE"
|
||||
msgstr ""
|
||||
msgstr "schreibe Debug-Protokolle in DATEI"
|
||||
|
||||
#: src/main/help.c:434
|
||||
#: src/main/help.c:450
|
||||
#, c-format
|
||||
msgid "Usage: %s [OPTION] [FILE]..."
|
||||
msgstr "Syntax: %s [OPTION] [DATEI]..."
|
||||
msgstr "Aufruf: %s [OPTION] [DATEI]..."
|
||||
|
||||
#: src/main/help.c:445
|
||||
#: src/main/help.c:461
|
||||
msgid ""
|
||||
"Concatenate FILE(s), or standard input, to standard output, with monitoring."
|
||||
msgstr ""
|
||||
"Verbindet DATEI(en) oder den Standard-Eingabe-Kanal mit dem Standard-Ausgabe-"
|
||||
"Kanal und misst den Datenstrom."
|
||||
|
||||
#: src/main/help.c:582
|
||||
#: src/main/help.c:598
|
||||
#, c-format
|
||||
msgid "Please report any bugs to: %s"
|
||||
msgstr "Bitte senden Sie Fehlerberichte an %s"
|
||||
|
||||
#: src/main/main.c:74
|
||||
#: src/main/main.c:230
|
||||
msgid "(input)"
|
||||
msgstr "(eingabe)"
|
||||
|
||||
#: src/main/main.c:319
|
||||
msgid "state allocation failed"
|
||||
msgstr "Zustandszuweisung fehlgeschlagen"
|
||||
msgstr "Speicherzuweisung für `state' fehlgeschlagen"
|
||||
|
||||
#: src/main/options.c:173
|
||||
#: src/main/options.c:144 src/pv/file.c:324
|
||||
msgid "failed to stat file"
|
||||
msgstr "konnte Dateiinformationen nicht lesen"
|
||||
|
||||
#: src/main/options.c:158
|
||||
msgid "is a directory"
|
||||
msgstr "ist ein Verzeichnis"
|
||||
|
||||
#: src/main/options.c:187
|
||||
msgid "failed to generate sysfs filename"
|
||||
msgstr "konnte Sysfs-Dateinamen nicht erzeugen"
|
||||
|
||||
#: src/main/options.c:209
|
||||
msgid "failed to read sysfs size file"
|
||||
msgstr "konnte Größe der Sysfs-Datei nicht lesen"
|
||||
|
||||
#: src/main/options.c:229
|
||||
msgid "failed to open block device"
|
||||
msgstr "konnte Blockgerät nicht öffnen"
|
||||
|
||||
#: src/main/options.c:239
|
||||
msgid "failed to determine size of block device"
|
||||
msgstr "konnte Größe des Blockgeräts nicht ermitteln"
|
||||
|
||||
#: src/main/options.c:344
|
||||
msgid "option structure allocation failed"
|
||||
msgstr "`option' konnte nicht allokiert werden"
|
||||
msgstr "Speicherzuweisung für `option' fehlgeschlagen"
|
||||
|
||||
#: src/main/options.c:192
|
||||
#: src/main/options.c:363
|
||||
msgid "option structure argv allocation failed"
|
||||
msgstr "`option' (argv) konnte nicht allokiert werden"
|
||||
msgstr "Speicherzuweisung für `argv' der Option fehlgeschlagen"
|
||||
|
||||
#: src/main/options.c:254
|
||||
#: src/main/options.c:425
|
||||
msgid "integer argument expected"
|
||||
msgstr "Ganzzahliges Argument erwartet"
|
||||
|
||||
#: src/main/options.c:265
|
||||
#: src/main/options.c:436
|
||||
msgid "numeric argument expected"
|
||||
msgstr "numerisches Argument erwartet"
|
||||
|
||||
#: src/main/options.c:276
|
||||
#: src/main/options.c:447
|
||||
msgid "process ID or pid:fd pair expected"
|
||||
msgstr "Prozess-ID oder PID:FD-Paar erwartet"
|
||||
|
||||
#: src/main/options.c:283
|
||||
#: src/main/options.c:454
|
||||
msgid "invalid process ID"
|
||||
msgstr "ungültige Prozess-ID"
|
||||
|
||||
#: src/main/options.c:384 src/pv/file.c:323
|
||||
msgid "failed to stat file"
|
||||
msgstr "Dateiinformationen konnten nicht gelesen werden"
|
||||
|
||||
#: src/main/options.c:487
|
||||
#: src/main/options.c:679
|
||||
#, c-format
|
||||
msgid "Try `%s --help' for more information."
|
||||
msgstr "`%s --help' zeigt weitere Informationen an."
|
||||
|
||||
#: src/main/options.c:489
|
||||
#: src/main/options.c:681
|
||||
#, c-format
|
||||
msgid "Try `%s -h' for more information."
|
||||
msgstr "`%s -h' zeigt weitere Informationen an."
|
||||
|
||||
#: src/main/options.c:520
|
||||
#: src/main/options.c:712
|
||||
msgid ""
|
||||
"cannot use line mode or transfer modifier options when watching file "
|
||||
"descriptors"
|
||||
msgstr ""
|
||||
"Beim Anzeigen von Dateideskriptoren können keine Optionen für den "
|
||||
"Beim Beobachten von Dateideskriptoren können keine Optionen für den "
|
||||
"Zeilenmodus oder den Übertragungsmodifikator verwendet werden"
|
||||
|
||||
#: src/main/options.c:529
|
||||
#: src/main/options.c:721
|
||||
msgid "cannot use cursor positioning when watching file descriptors"
|
||||
msgstr ""
|
||||
"Beim Anzeigen von Dateideskriptoren können keine Zeilenmodus- oder "
|
||||
"Übertragungsmodifikatoroptionen verwendet werden."
|
||||
"Beim Beobachten von Dateideskriptoren kann Cursor-Positionierung nicht "
|
||||
"verwendet werden"
|
||||
|
||||
#: src/main/options.c:538
|
||||
#: src/main/options.c:730
|
||||
msgid "cannot use remote control when watching file descriptors"
|
||||
msgstr ""
|
||||
"kann keine Fernbedienung verwenden, wenn Dateideskriptoren angezeigt werden"
|
||||
"Beim Beobachten von Dateideskriptoren kann die Fernbedienung nicht verwenden "
|
||||
"werden"
|
||||
|
||||
#: src/main/options.c:547
|
||||
#: src/main/options.c:739
|
||||
msgid "cannot transfer files when watching file descriptors"
|
||||
msgstr ""
|
||||
"Dateien können beim Betrachten von Dateideskriptoren nicht übertragen werden"
|
||||
"Beim Beobachten von Dateideskriptoren können Dateien nicht übertragen werden"
|
||||
|
||||
#: src/main/options.c:562
|
||||
#: src/main/options.c:754
|
||||
msgid "not available on systems without /proc/self/fdinfo"
|
||||
msgstr "Nicht verfügbar auf Systemen ohne /proc/self/fdinfo"
|
||||
|
||||
#: src/main/remote.c:295
|
||||
#: src/main/remote.c:304
|
||||
msgid "message not received"
|
||||
msgstr "Nachricht nicht empfangen"
|
||||
|
||||
#: src/main/remote.c:422
|
||||
#: src/main/remote.c:431
|
||||
msgid "SA_SIGINFO not supported on this system"
|
||||
msgstr "SA_SIGINFO wird auf diesem System nicht unterstützt"
|
||||
|
||||
#: src/main/version.c:28
|
||||
msgid "License: GPLv3+ <https://www.gnu.org/licenses/gpl-3.0.html>"
|
||||
msgstr ""
|
||||
msgstr "Lizenz: GPLv3+ <https://www.gnu.org/licenses/gpl-3.0.html>"
|
||||
|
||||
#: src/main/version.c:29
|
||||
msgid "This is free software: you are free to change and redistribute it."
|
||||
msgstr ""
|
||||
msgstr "Dies ist freie Software: Sie dürfen sie verändern und weiterverteilen."
|
||||
|
||||
#: src/main/version.c:30
|
||||
msgid "There is NO WARRANTY, to the extent permitted by law."
|
||||
msgstr ""
|
||||
msgstr "Es besteht KEINE GARANTIE, soweit dies gesetzlich zulässig ist."
|
||||
|
||||
#: src/main/version.c:32
|
||||
msgid "Project web site"
|
||||
msgstr ""
|
||||
msgstr "Projekt-Website"
|
||||
|
||||
#: src/pv/cursor.c:87
|
||||
#: src/pv/cursor.c:61
|
||||
msgid "failed to get terminal name"
|
||||
msgstr "Terminalname konnte nicht gelesen werden"
|
||||
msgstr "konnte Terminalname nicht lesen"
|
||||
|
||||
#: src/pv/cursor.c:130
|
||||
#: src/pv/cursor.c:106
|
||||
msgid "failed to open lock file"
|
||||
msgstr "Sperrdatei konnte nicht geöffnet werden"
|
||||
msgstr "konnte Sperrdatei nicht öffnen"
|
||||
|
||||
#: src/pv/cursor.c:163
|
||||
#: src/pv/cursor.c:139
|
||||
msgid "lock attempt failed"
|
||||
msgstr "Sperrversuch fehlgeschlagen"
|
||||
|
||||
#: src/pv/cursor.c:424
|
||||
#: src/pv/cursor.c:400
|
||||
msgid "failed to open terminal"
|
||||
msgstr "Terminal konnte nicht geöffnet werden"
|
||||
msgstr "konnte Terminal nicht öffnen"
|
||||
|
||||
#: src/pv/display.c:192
|
||||
#: src/pv/display.c:233
|
||||
msgid "yzafpnum kMGTPEZY"
|
||||
msgstr ""
|
||||
msgstr "yzafpnµm kMGTPEZY"
|
||||
|
||||
#: src/pv/display.c:210
|
||||
#: src/pv/display.c:251
|
||||
msgid "yzafpnum KMGTPEZY"
|
||||
msgstr ""
|
||||
msgstr "yzafpnµm KMGTPEZY"
|
||||
|
||||
#: src/pv/display.c:746 src/pv/transfer.c:910
|
||||
#: src/pv/display.c:681 src/pv/transfer.c:1011
|
||||
msgid "buffer allocation failed"
|
||||
msgstr "Puffer konnte nicht allokiert werden"
|
||||
msgstr "Speicherzuweisung für den Puffer fehlgeschlagen"
|
||||
|
||||
#: src/pv/display.c:845
|
||||
#: src/pv/display.c:810
|
||||
msgid "b"
|
||||
msgstr ""
|
||||
msgstr "b"
|
||||
|
||||
#: src/pv/display.c:848 src/pv/transfer.c:595
|
||||
#: src/pv/display.c:813 src/pv/transfer.c:602
|
||||
msgid "B"
|
||||
msgstr "B"
|
||||
|
||||
#: src/pv/display.c:890 src/pv/display.c:907
|
||||
#: src/pv/display.c:857 src/pv/display.c:872 src/pv/display.c:1091
|
||||
#: src/pv/loop.c:549
|
||||
msgid "b/s"
|
||||
msgstr ""
|
||||
msgstr "b/s"
|
||||
|
||||
#: src/pv/display.c:895 src/pv/display.c:912
|
||||
#: src/pv/display.c:861 src/pv/display.c:876 src/pv/display.c:1095
|
||||
msgid "/s"
|
||||
msgstr ""
|
||||
msgstr "/s"
|
||||
|
||||
#: src/pv/display.c:895 src/pv/display.c:912
|
||||
#: src/pv/display.c:861 src/pv/display.c:876 src/pv/display.c:1095
|
||||
#: src/pv/loop.c:549
|
||||
msgid "B/s"
|
||||
msgstr ""
|
||||
msgstr "B/s"
|
||||
|
||||
#: src/pv/display.c:940 src/pv/display.c:944 src/pv/display.c:1010
|
||||
#: src/pv/display.c:904 src/pv/display.c:908
|
||||
msgid "ETA"
|
||||
msgstr "ETA"
|
||||
|
||||
#: src/pv/file.c:148
|
||||
#: src/pv/display.c:974
|
||||
msgid "FIN"
|
||||
msgstr "Endzeit"
|
||||
|
||||
#: src/pv/file.c:149
|
||||
msgid "failed to seek to start of output"
|
||||
msgstr "Konnte nicht versuchen, die Ausgabe zu starten"
|
||||
msgstr "Konnte nicht zum Anfang der Ausgabe springen"
|
||||
|
||||
#: src/pv/file.c:293
|
||||
#: src/pv/file.c:294
|
||||
msgid "failed to close file"
|
||||
msgstr "Datei konnte nicht geschlossen werden"
|
||||
msgstr "konnte Datei nicht schließen"
|
||||
|
||||
#: src/pv/file.c:316
|
||||
#: src/pv/file.c:317
|
||||
msgid "failed to read file"
|
||||
msgstr "Datei konnte nicht gelesen werden"
|
||||
msgstr "konnte Datei nicht lesen"
|
||||
|
||||
#: src/pv/file.c:331
|
||||
#: src/pv/file.c:332
|
||||
msgid "failed to stat output file"
|
||||
msgstr "Dateiinformationen für Ausgabe-Datei konnten nicht gelesen werden"
|
||||
msgstr "konnte Dateiinformationen für Ausgabe-Datei nicht lesen"
|
||||
|
||||
#: src/pv/file.c:353
|
||||
#: src/pv/file.c:354
|
||||
msgid "input file is output file"
|
||||
msgstr "Eingabe-Datei ist Ausgabe-Datei"
|
||||
|
||||
#: src/pv/file.c:411
|
||||
#: src/pv/file.c:412
|
||||
msgid "(none)"
|
||||
msgstr ""
|
||||
msgstr "(keine)"
|
||||
|
||||
#: src/pv/file.c:413
|
||||
#: src/pv/file.c:414
|
||||
msgid "(stdin)"
|
||||
msgstr ""
|
||||
msgstr "(stdin)"
|
||||
|
||||
#: src/pv/loop.c:570 src/pv/loop.c:621 src/pv/loop.c:662 src/pv/watchpid.c:99
|
||||
#: src/pv/loop.c:548
|
||||
#, fuzzy
|
||||
msgid "rate min/avg/max/mdev"
|
||||
msgstr "Rate min/mittel/max/mdev"
|
||||
|
||||
#: src/pv/loop.c:560
|
||||
msgid "rate not measured"
|
||||
msgstr "Übertragungsrate nicht gemessen"
|
||||
|
||||
#: src/pv/loop.c:767 src/pv/loop.c:818 src/pv/loop.c:859 src/pv/watchpid.c:99
|
||||
#: src/pv/watchpid.c:109 src/pv/watchpid.c:120 src/pv/watchpid.c:128
|
||||
#: src/pv/watchpid.c:165 src/pv/watchpid.c:184 src/pv/watchpid.c:192
|
||||
#: src/pv/watchpid.c:202 src/pv/watchpid.c:293 src/pv/watchpid.c:301
|
||||
#: src/pv/watchpid.c:377 src/pv/watchpid.c:398
|
||||
#: src/pv/watchpid.c:202 src/pv/watchpid.c:300 src/pv/watchpid.c:308
|
||||
#: src/pv/watchpid.c:384 src/pv/watchpid.c:405
|
||||
msgid "pid"
|
||||
msgstr ""
|
||||
msgstr "pid"
|
||||
|
||||
#: src/pv/state.c:36
|
||||
#: src/pv/state.c:40
|
||||
msgid "history structure allocation failed"
|
||||
msgstr ""
|
||||
msgstr "Speicherzuweisung für `history' fehlgeschlagen"
|
||||
|
||||
#: src/pv/state.c:386 src/pv/state.c:397
|
||||
#: src/pv/state.c:572 src/pv/state.c:583
|
||||
msgid "file list allocation failed"
|
||||
msgstr ""
|
||||
msgstr "Speicherzuweisung für die Dateiliste fehlgeschlagen"
|
||||
|
||||
#: src/pv/transfer.c:457
|
||||
#: src/pv/transfer.c:464
|
||||
msgid "read failed"
|
||||
msgstr "read-Aufruf fehlgeschlagen"
|
||||
|
||||
#: src/pv/transfer.c:480
|
||||
#: src/pv/transfer.c:487
|
||||
msgid "warning: read errors detected"
|
||||
msgstr "warnung: lesefehler erkannt"
|
||||
|
||||
#: src/pv/transfer.c:496
|
||||
#: src/pv/transfer.c:503
|
||||
msgid "file is not seekable"
|
||||
msgstr "datei ist nicht durchsuchbar"
|
||||
msgstr "Datei ist nicht durchsuchbar"
|
||||
|
||||
#: src/pv/transfer.c:574
|
||||
#: src/pv/transfer.c:581
|
||||
msgid "failed to seek past error"
|
||||
msgstr "konnte den Fehler nicht überwinden"
|
||||
|
||||
#: src/pv/transfer.c:594
|
||||
#: src/pv/transfer.c:601
|
||||
msgid "skipped past read error"
|
||||
msgstr "über den Lesefehler hinaus verschoben"
|
||||
|
||||
#: src/pv/transfer.c:634
|
||||
#: src/pv/transfer.c:642
|
||||
msgid "no transfer buffer allocated"
|
||||
msgstr ""
|
||||
msgstr "Speicherzuweisung für den Transferpuffer fehlgeschlagen"
|
||||
|
||||
#: src/pv/transfer.c:647
|
||||
msgid "failed to set alarm signal handler"
|
||||
msgstr ""
|
||||
#: src/pv/transfer.c:684
|
||||
msgid "failed to set interval timer"
|
||||
msgstr "konnte Intervall-Timer nicht setzen"
|
||||
|
||||
#: src/pv/transfer.c:774
|
||||
#: src/pv/transfer.c:710
|
||||
msgid "failed to clear interval timer"
|
||||
msgstr "konnte Intervall-Timer nicht löschen"
|
||||
|
||||
#: src/pv/transfer.c:740
|
||||
msgid "line position buffer allocation failed"
|
||||
msgstr "Zuweisung des Zeilenpuffers fehlgeschlagen"
|
||||
|
||||
#: src/pv/transfer.c:872
|
||||
msgid "write failed"
|
||||
msgstr "write-Aufruf fehlgeschlagen"
|
||||
|
||||
#: src/pv/transfer.c:1007
|
||||
#: src/pv/transfer.c:1109
|
||||
msgid "select call failed"
|
||||
msgstr "select-Aufruf fehlgeschlagen"
|
||||
|
||||
#: src/pv/watchpid.c:109 src/pv/watchpid.c:121 src/pv/watchpid.c:130
|
||||
#: src/pv/watchpid.c:184 src/pv/watchpid.c:193 src/pv/watchpid.c:204
|
||||
msgid "fd"
|
||||
msgstr ""
|
||||
msgstr "fd"
|
||||
|
||||
#: src/pv/watchpid.c:130 src/pv/watchpid.c:204
|
||||
msgid "not a regular file or block device"
|
||||
msgstr "keine normale Datei oder Blockgerät"
|
||||
msgstr "ist weder eine normale Datei noch ein Blockgerät"
|
||||
|
||||
@@ -0,0 +1,535 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Report-Msgid-Bugs-To: pv@ivarch.com\n"
|
||||
"POT-Creation-Date: 2024-12-02 17:56+0000\n"
|
||||
"Language: es\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: src/main/help.c:284
|
||||
msgid "show progress bar"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:287
|
||||
msgid "show elapsed time"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:290
|
||||
msgid "show estimated time of arrival (completion)"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:293
|
||||
msgid "show absolute estimated time of arrival (completion)"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:296
|
||||
msgid "show data transfer rate counter"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:299
|
||||
msgid "show data transfer average rate counter"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:302
|
||||
msgid "show number of bytes transferred"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:305
|
||||
msgid "show percentage of transfer buffer in use"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:307
|
||||
msgid "NUM"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:308
|
||||
msgid "show NUM bytes last written"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:310
|
||||
msgid "FORMAT"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:311
|
||||
msgid "set output format to FORMAT"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:314
|
||||
msgid "output percentages, not visual information"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:317
|
||||
msgid "do not output any transfer information at all"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:321
|
||||
msgid "show number of bits transferred"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:324
|
||||
msgid "treat suffixes as multiples of 1000 rather than 1024"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:327
|
||||
msgid "display nothing until first byte transferred"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:329 src/main/help.c:344 src/main/help.c:347
|
||||
msgid "SEC"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:330
|
||||
msgid "display nothing until SEC seconds have passed"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:332
|
||||
msgid "SIZE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:333
|
||||
msgid "set estimated data size to SIZE bytes"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:336
|
||||
msgid "if size unknown, show rate vs max rate"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:339
|
||||
msgid "count lines instead of bytes"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:342
|
||||
msgid "lines are null-terminated"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:345
|
||||
msgid "update every SEC seconds"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:348
|
||||
msgid "compute average rate over past SEC seconds (default 30s)"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:350
|
||||
msgid "WIDTH"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:351
|
||||
msgid "assume terminal is WIDTH characters wide"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:353
|
||||
msgid "HEIGHT"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:354
|
||||
msgid "assume terminal is HEIGHT rows high"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:356
|
||||
msgid "NAME"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:357
|
||||
msgid "prefix visual information with NAME"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:359
|
||||
msgid "SPEC"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:360
|
||||
msgid "also send progress to SPEC"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:363
|
||||
msgid "output transfer statistics at the end"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:366
|
||||
msgid "output even if standard error is not a terminal"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:369
|
||||
msgid "use cursor positioning escape sequences"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:372 src/main/help.c:402 src/main/help.c:414
|
||||
#: src/main/help.c:424
|
||||
msgid "FILE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:373
|
||||
msgid "write output to FILE instead of stdout"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:375
|
||||
msgid "RATE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:376
|
||||
msgid "limit transfer to RATE bytes per second"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:378 src/main/help.c:387
|
||||
msgid "BYTES"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:379
|
||||
msgid "use a buffer size of BYTES"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:382
|
||||
msgid "never use splice(), always use read/write"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:385
|
||||
msgid "skip read errors in input"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:388
|
||||
msgid "skip errors in BYTES blocks at a time"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:391
|
||||
msgid "stop after --size bytes have been transferred"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:394
|
||||
msgid "flush cache to disk after every write"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:397
|
||||
msgid "use direct I/O to bypass cache"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:400
|
||||
msgid "discard input instead of writing to output"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:403
|
||||
msgid "write all input to FILE before writing to output"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:405
|
||||
msgid "PID[:FD]"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:406
|
||||
msgid "watch file FD opened by process PID"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:409
|
||||
msgid "PID"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:410
|
||||
msgid "update settings of process PID"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:415
|
||||
msgid "save process ID in FILE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:418
|
||||
msgid "show this help and exit"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:421
|
||||
msgid "show version information and exit"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:425
|
||||
msgid "write debug logs to FILE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:450
|
||||
#, c-format
|
||||
msgid "Usage: %s [OPTION] [FILE]..."
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:461
|
||||
msgid ""
|
||||
"Concatenate FILE(s), or standard input, to standard output, with monitoring."
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:598
|
||||
#, c-format
|
||||
msgid "Please report any bugs to: %s"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/main.c:230
|
||||
msgid "(input)"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/main.c:319
|
||||
msgid "state allocation failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:144 src/pv/file.c:324
|
||||
msgid "failed to stat file"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:158
|
||||
msgid "is a directory"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:187
|
||||
msgid "failed to generate sysfs filename"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:209
|
||||
msgid "failed to read sysfs size file"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:229
|
||||
msgid "failed to open block device"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:239
|
||||
msgid "failed to determine size of block device"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:344
|
||||
msgid "option structure allocation failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:363
|
||||
msgid "option structure argv allocation failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:425
|
||||
msgid "integer argument expected"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:436
|
||||
msgid "numeric argument expected"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:447
|
||||
msgid "process ID or pid:fd pair expected"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:454
|
||||
msgid "invalid process ID"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:679
|
||||
#, c-format
|
||||
msgid "Try `%s --help' for more information."
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:681
|
||||
#, c-format
|
||||
msgid "Try `%s -h' for more information."
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:712
|
||||
msgid ""
|
||||
"cannot use line mode or transfer modifier options when watching file "
|
||||
"descriptors"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:721
|
||||
msgid "cannot use cursor positioning when watching file descriptors"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:730
|
||||
msgid "cannot use remote control when watching file descriptors"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:739
|
||||
msgid "cannot transfer files when watching file descriptors"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:754
|
||||
msgid "not available on systems without /proc/self/fdinfo"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/remote.c:304
|
||||
msgid "message not received"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/remote.c:431
|
||||
msgid "SA_SIGINFO not supported on this system"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/version.c:28
|
||||
msgid "License: GPLv3+ <https://www.gnu.org/licenses/gpl-3.0.html>"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/version.c:29
|
||||
msgid "This is free software: you are free to change and redistribute it."
|
||||
msgstr ""
|
||||
|
||||
#: src/main/version.c:30
|
||||
msgid "There is NO WARRANTY, to the extent permitted by law."
|
||||
msgstr ""
|
||||
|
||||
#: src/main/version.c:32
|
||||
msgid "Project web site"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/cursor.c:61
|
||||
msgid "failed to get terminal name"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/cursor.c:106
|
||||
msgid "failed to open lock file"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/cursor.c:139
|
||||
msgid "lock attempt failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/cursor.c:400
|
||||
msgid "failed to open terminal"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:233
|
||||
msgid "yzafpnum kMGTPEZY"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:251
|
||||
msgid "yzafpnum KMGTPEZY"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:681 src/pv/transfer.c:1011
|
||||
msgid "buffer allocation failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:810
|
||||
msgid "b"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:813 src/pv/transfer.c:602
|
||||
msgid "B"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:857 src/pv/display.c:872 src/pv/display.c:1091
|
||||
#: src/pv/loop.c:549
|
||||
msgid "b/s"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:861 src/pv/display.c:876 src/pv/display.c:1095
|
||||
msgid "/s"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:861 src/pv/display.c:876 src/pv/display.c:1095
|
||||
#: src/pv/loop.c:549
|
||||
msgid "B/s"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:904 src/pv/display.c:908
|
||||
msgid "ETA"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:974
|
||||
msgid "FIN"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/file.c:149
|
||||
msgid "failed to seek to start of output"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/file.c:294
|
||||
msgid "failed to close file"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/file.c:317
|
||||
msgid "failed to read file"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/file.c:332
|
||||
msgid "failed to stat output file"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/file.c:354
|
||||
msgid "input file is output file"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/file.c:412
|
||||
msgid "(none)"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/file.c:414
|
||||
msgid "(stdin)"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/loop.c:548
|
||||
msgid "rate min/avg/max/mdev"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/loop.c:560
|
||||
msgid "rate not measured"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/loop.c:767 src/pv/loop.c:818 src/pv/loop.c:859 src/pv/watchpid.c:99
|
||||
#: src/pv/watchpid.c:109 src/pv/watchpid.c:120 src/pv/watchpid.c:128
|
||||
#: src/pv/watchpid.c:165 src/pv/watchpid.c:184 src/pv/watchpid.c:192
|
||||
#: src/pv/watchpid.c:202 src/pv/watchpid.c:300 src/pv/watchpid.c:308
|
||||
#: src/pv/watchpid.c:384 src/pv/watchpid.c:405
|
||||
msgid "pid"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/state.c:40
|
||||
msgid "history structure allocation failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/state.c:572 src/pv/state.c:583
|
||||
msgid "file list allocation failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:464
|
||||
msgid "read failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:487
|
||||
msgid "warning: read errors detected"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:503
|
||||
msgid "file is not seekable"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:581
|
||||
msgid "failed to seek past error"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:601
|
||||
msgid "skipped past read error"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:642
|
||||
msgid "no transfer buffer allocated"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:684
|
||||
msgid "failed to set interval timer"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:710
|
||||
msgid "failed to clear interval timer"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:740
|
||||
msgid "line position buffer allocation failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:872
|
||||
msgid "write failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:1109
|
||||
msgid "select call failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/watchpid.c:109 src/pv/watchpid.c:121 src/pv/watchpid.c:130
|
||||
#: src/pv/watchpid.c:184 src/pv/watchpid.c:193 src/pv/watchpid.c:204
|
||||
msgid "fd"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/watchpid.c:130 src/pv/watchpid.c:204
|
||||
msgid "not a regular file or block device"
|
||||
msgstr ""
|
||||
@@ -1,9 +1,15 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Report-Msgid-Bugs-To: pv@ivarch.com\n"
|
||||
"POT-Creation-Date: 2023-11-19 14:19+0000\n"
|
||||
"POT-Creation-Date: 2024-12-02 17:56+0000\n"
|
||||
"PO-Revision-Date: 2024-10-12 11:13+0000\n"
|
||||
"Last-Translator: a-j-wood <a-j-wood@users.noreply.translate.codeberg.org>\n"
|
||||
"Language-Team: French <https://translate.codeberg.org/projects/pv/pv/fr/>\n"
|
||||
"Language: fr\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n > 1;\n"
|
||||
"X-Generator: Weblate 5.7.2\n"
|
||||
"Date: 1999-06-01 15:18:29+0100\n"
|
||||
"From: Andrew Wood <ivarch@ubik>\n"
|
||||
"Xgettext-Options: --default-domain=pkgbuild --directory=./.pkgdir --add-"
|
||||
@@ -22,79 +28,79 @@ msgstr ""
|
||||
|
||||
#: src/main/help.c:284
|
||||
msgid "show progress bar"
|
||||
msgstr "affiche la barre de progression"
|
||||
msgstr "afficher la barre de progression"
|
||||
|
||||
#: src/main/help.c:287
|
||||
msgid "show elapsed time"
|
||||
msgstr "affiche le temps écoulé"
|
||||
msgstr "afficher le temps écoulé"
|
||||
|
||||
#: src/main/help.c:290
|
||||
msgid "show estimated time of arrival (completion)"
|
||||
msgstr "affiche l'heure approximative de l'achèvement de la tâche"
|
||||
msgstr "afficher l'heure approximative de l'achèvement de la tâche"
|
||||
|
||||
#: src/main/help.c:293
|
||||
msgid "show absolute estimated time of arrival (completion)"
|
||||
msgstr "affiche l'heure absolute de l'achèvement de la tâche"
|
||||
msgstr "afficher l'heure absolute de l'achèvement de la tâche"
|
||||
|
||||
#: src/main/help.c:296
|
||||
msgid "show data transfer rate counter"
|
||||
msgstr "affiche le taux de tranfert des données"
|
||||
msgstr "afficher le taux de tranfert des données"
|
||||
|
||||
#: src/main/help.c:299
|
||||
msgid "show data transfer average rate counter"
|
||||
msgstr "afficher le compteur de taux moyen de transfert de données"
|
||||
|
||||
#: src/main/help.c:301 src/main/help.c:329 src/main/help.c:341
|
||||
msgid "SEC"
|
||||
msgstr "SEC"
|
||||
|
||||
#: src/main/help.c:302
|
||||
msgid "compute average rate over past SEC seconds (default 30s)"
|
||||
msgstr ""
|
||||
msgid "show number of bytes transferred"
|
||||
msgstr "afficher le nombre d'octets transférés"
|
||||
|
||||
#: src/main/help.c:305
|
||||
msgid "show number of bytes transferred"
|
||||
msgstr "affiche le nombre d'octets transférés"
|
||||
|
||||
#: src/main/help.c:308
|
||||
msgid "show number of bits transferred"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:311
|
||||
msgid "show percentage of transfer buffer in use"
|
||||
msgstr "afficher le pourcentage de tampon de transfert utilisé"
|
||||
|
||||
#: src/main/help.c:313
|
||||
#: src/main/help.c:307
|
||||
msgid "NUM"
|
||||
msgstr ""
|
||||
msgstr "NUM"
|
||||
|
||||
#: src/main/help.c:314
|
||||
#: src/main/help.c:308
|
||||
msgid "show NUM bytes last written"
|
||||
msgstr "affiche NUM octets pour la dernière fois écrits"
|
||||
msgstr "afficher les derniers NUM octets écrits"
|
||||
|
||||
#: src/main/help.c:316
|
||||
#: src/main/help.c:310
|
||||
msgid "FORMAT"
|
||||
msgstr ""
|
||||
msgstr "FORMAT"
|
||||
|
||||
#: src/main/help.c:317
|
||||
#: src/main/help.c:311
|
||||
msgid "set output format to FORMAT"
|
||||
msgstr "définir le format de sortie sur FORMAT"
|
||||
|
||||
#: src/main/help.c:320
|
||||
#: src/main/help.c:314
|
||||
msgid "output percentages, not visual information"
|
||||
msgstr "imprime en pourcentage, pas les informations visuelles"
|
||||
msgstr "imprimer en pourcentage plutôt que des informations visuelles"
|
||||
|
||||
#: src/main/help.c:323
|
||||
#: src/main/help.c:317
|
||||
msgid "do not output any transfer information at all"
|
||||
msgstr "n'afficher aucune information de transfert"
|
||||
|
||||
#: src/main/help.c:321
|
||||
msgid "show number of bits transferred"
|
||||
msgstr "afficher le nombre de bits transférés"
|
||||
|
||||
#: src/main/help.c:324
|
||||
msgid "treat suffixes as multiples of 1000 rather than 1024"
|
||||
msgstr "traiter les suffixes comme des multiples de 1000 au lieu de 1024"
|
||||
|
||||
#: src/main/help.c:327
|
||||
msgid "display nothing until first byte transferred"
|
||||
msgstr "ne rien afficher avant qu'au moins un octet soit tranféré"
|
||||
|
||||
#: src/main/help.c:329 src/main/help.c:344 src/main/help.c:347
|
||||
msgid "SEC"
|
||||
msgstr "SEC"
|
||||
|
||||
#: src/main/help.c:330
|
||||
msgid "display nothing until SEC seconds have passed"
|
||||
msgstr "n'afficher rien jusqu'à ce que SEC secondes se soient écoulées"
|
||||
msgstr "ne rien afficher jusqu'à ce que SEC secondes se soient écoulées"
|
||||
|
||||
#: src/main/help.c:332
|
||||
msgid "SIZE"
|
||||
@@ -102,192 +108,249 @@ msgstr "TAILLE"
|
||||
|
||||
#: src/main/help.c:333
|
||||
msgid "set estimated data size to SIZE bytes"
|
||||
msgstr "ajuste la taille estimée des données à TAILLE octets"
|
||||
msgstr "ajuster la taille estimée des données à TAILLE octets"
|
||||
|
||||
#: src/main/help.c:336
|
||||
msgid "count lines instead of bytes"
|
||||
msgstr "compte les lignes au lieu des octets"
|
||||
msgid "if size unknown, show rate vs max rate"
|
||||
msgstr ""
|
||||
"si la taille est inconnue, afficher le taux de transfert par rapport au taux "
|
||||
"de transfert max"
|
||||
|
||||
#: src/main/help.c:339
|
||||
msgid "lines are null-terminated"
|
||||
msgstr "les lignes sont terminées par un nul"
|
||||
msgid "count lines instead of bytes"
|
||||
msgstr "compter les lignes au lieu des octets"
|
||||
|
||||
#: src/main/help.c:342
|
||||
msgid "update every SEC seconds"
|
||||
msgstr "mise-à-jour toute les SEC secondes"
|
||||
msgid "lines are null-terminated"
|
||||
msgstr "les lignes sont terminées par un caractère nul"
|
||||
|
||||
#: src/main/help.c:344
|
||||
#: src/main/help.c:345
|
||||
msgid "update every SEC seconds"
|
||||
msgstr "mettre à jour toutes les SEC secondes"
|
||||
|
||||
#: src/main/help.c:348
|
||||
msgid "compute average rate over past SEC seconds (default 30s)"
|
||||
msgstr ""
|
||||
"calculer le taux moyen d'après les SEC dernières secondes (30s par défaut)"
|
||||
|
||||
#: src/main/help.c:350
|
||||
msgid "WIDTH"
|
||||
msgstr "LARGEUR"
|
||||
|
||||
#: src/main/help.c:345
|
||||
#: src/main/help.c:351
|
||||
msgid "assume terminal is WIDTH characters wide"
|
||||
msgstr "présumer la largeur du terminal à LARGEUR caractères"
|
||||
|
||||
#: src/main/help.c:347
|
||||
#: src/main/help.c:353
|
||||
msgid "HEIGHT"
|
||||
msgstr "HAUTEUR"
|
||||
|
||||
#: src/main/help.c:348
|
||||
#: src/main/help.c:354
|
||||
msgid "assume terminal is HEIGHT rows high"
|
||||
msgstr "présumer la hauteur du terminal à HAUTEUR lignes"
|
||||
|
||||
#: src/main/help.c:350
|
||||
#: src/main/help.c:356
|
||||
msgid "NAME"
|
||||
msgstr "NOM"
|
||||
|
||||
#: src/main/help.c:351
|
||||
#: src/main/help.c:357
|
||||
msgid "prefix visual information with NAME"
|
||||
msgstr "préfixer les informations visuelles avec NOM"
|
||||
|
||||
#: src/main/help.c:354
|
||||
msgid "output even if standard error is not a terminal"
|
||||
msgstr "imprime vers la sortie d'erreur même si ce n'est pas un terminal"
|
||||
#: src/main/help.c:359
|
||||
msgid "SPEC"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:357
|
||||
#: src/main/help.c:360
|
||||
msgid "also send progress to SPEC"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:363
|
||||
msgid "output transfer statistics at the end"
|
||||
msgstr "afficher les statistiques de transfert à la fin"
|
||||
|
||||
#: src/main/help.c:366
|
||||
msgid "output even if standard error is not a terminal"
|
||||
msgstr ""
|
||||
"imprimer vers la sortie d'erreur standard même si ce n'est pas un terminal"
|
||||
|
||||
#: src/main/help.c:369
|
||||
msgid "use cursor positioning escape sequences"
|
||||
msgstr "utiliser les séquences d'échappements de positionnement de curseur"
|
||||
|
||||
#: src/main/help.c:360
|
||||
#: src/main/help.c:372 src/main/help.c:402 src/main/help.c:414
|
||||
#: src/main/help.c:424
|
||||
msgid "FILE"
|
||||
msgstr "FICHIER"
|
||||
|
||||
#: src/main/help.c:373
|
||||
msgid "write output to FILE instead of stdout"
|
||||
msgstr "écrire la sortie dans FICHIER au lieu de la sortie standard"
|
||||
|
||||
#: src/main/help.c:375
|
||||
msgid "RATE"
|
||||
msgstr "TAUX"
|
||||
|
||||
#: src/main/help.c:361
|
||||
#: src/main/help.c:376
|
||||
msgid "limit transfer to RATE bytes per second"
|
||||
msgstr "limite le taux de transfer à TAUX octets par seconde"
|
||||
msgstr "limite le taux de transfert à TAUX octets par seconde"
|
||||
|
||||
#: src/main/help.c:363 src/main/help.c:372
|
||||
#: src/main/help.c:378 src/main/help.c:387
|
||||
msgid "BYTES"
|
||||
msgstr "OCTETS"
|
||||
|
||||
#: src/main/help.c:364
|
||||
#: src/main/help.c:379
|
||||
msgid "use a buffer size of BYTES"
|
||||
msgstr "Utiliser une mémoire tampon de OCTETS octets"
|
||||
|
||||
#: src/main/help.c:367
|
||||
#: src/main/help.c:382
|
||||
msgid "never use splice(), always use read/write"
|
||||
msgstr "n'utilisez jamais splice(), utilisez toujours read/write"
|
||||
msgstr "ne jamais utiliser splice(), toujours utiliser read/write"
|
||||
|
||||
#: src/main/help.c:370
|
||||
#: src/main/help.c:385
|
||||
msgid "skip read errors in input"
|
||||
msgstr "ignorer les erreurs de lecture dans l'entrée"
|
||||
|
||||
#: src/main/help.c:373
|
||||
#: src/main/help.c:388
|
||||
msgid "skip errors in BYTES blocks at a time"
|
||||
msgstr ""
|
||||
msgstr "ignorer les erreurs dans OCTETS blocs à la fois"
|
||||
|
||||
#: src/main/help.c:376
|
||||
#: src/main/help.c:391
|
||||
msgid "stop after --size bytes have been transferred"
|
||||
msgstr "arrêter après le transfert de --size octets"
|
||||
|
||||
#: src/main/help.c:379
|
||||
#: src/main/help.c:394
|
||||
msgid "flush cache to disk after every write"
|
||||
msgstr ""
|
||||
msgstr "vider le cache sur le disque après chaque écriture"
|
||||
|
||||
#: src/main/help.c:382
|
||||
#: src/main/help.c:397
|
||||
msgid "use direct I/O to bypass cache"
|
||||
msgstr ""
|
||||
msgstr "utiliser les E/S directes pour contourner le cache"
|
||||
|
||||
#: src/main/help.c:385
|
||||
#: src/main/help.c:400
|
||||
msgid "discard input instead of writing to output"
|
||||
msgstr ""
|
||||
msgstr "rejeter l'entrée au lieu de l'écrire vers la sortie"
|
||||
|
||||
#: src/main/help.c:388
|
||||
#: src/main/help.c:403
|
||||
msgid "write all input to FILE before writing to output"
|
||||
msgstr "écrire toute l'entrée vers FICHIER avant de l'écrire vers la sortie"
|
||||
|
||||
#: src/main/help.c:405
|
||||
msgid "PID[:FD]"
|
||||
msgstr "PID[:FD]"
|
||||
|
||||
#: src/main/help.c:406
|
||||
msgid "watch file FD opened by process PID"
|
||||
msgstr "surveiller le fichier FD ouvert par le processus PID"
|
||||
|
||||
#: src/main/help.c:409
|
||||
msgid "PID"
|
||||
msgstr "PID"
|
||||
|
||||
#: src/main/help.c:389
|
||||
#: src/main/help.c:410
|
||||
msgid "update settings of process PID"
|
||||
msgstr "mettre-à-jour la configuration du processus PID"
|
||||
msgstr "mettre à jour la configuration du processus PID"
|
||||
|
||||
#: src/main/help.c:393 src/main/help.c:408
|
||||
msgid "FILE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:394
|
||||
#: src/main/help.c:415
|
||||
msgid "save process ID in FILE"
|
||||
msgstr "enregistrer l'ID de processus dans FILE"
|
||||
msgstr "enregistrer l'ID de processus dans FICHIER"
|
||||
|
||||
#: src/main/help.c:397
|
||||
msgid "PID[:FD]"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:398
|
||||
msgid "watch file FD opened by process PID"
|
||||
msgstr "regarder le fichier FD ouvert par le processus PID"
|
||||
|
||||
#: src/main/help.c:402
|
||||
#: src/main/help.c:418
|
||||
msgid "show this help and exit"
|
||||
msgstr "afficher cette aide puis quitter"
|
||||
|
||||
#: src/main/help.c:405
|
||||
#: src/main/help.c:421
|
||||
msgid "show version information and exit"
|
||||
msgstr "afficher la version puis quitter"
|
||||
|
||||
#: src/main/help.c:409
|
||||
#: src/main/help.c:425
|
||||
msgid "write debug logs to FILE"
|
||||
msgstr ""
|
||||
msgstr "écrire les journaux de déboggage vers FICHIER"
|
||||
|
||||
#: src/main/help.c:434
|
||||
#: src/main/help.c:450
|
||||
#, c-format
|
||||
msgid "Usage: %s [OPTION] [FILE]..."
|
||||
msgstr "Utilisation : %s [OPTIONS] [FICHIER]..."
|
||||
|
||||
#: src/main/help.c:445
|
||||
#: src/main/help.c:461
|
||||
msgid ""
|
||||
"Concatenate FILE(s), or standard input, to standard output, with monitoring."
|
||||
msgstr ""
|
||||
"Concatène FICHIER(s), ou l'entrée standard, sur la sortie standard avec "
|
||||
"Concaténer FICHIER(s), ou l'entrée standard, sur la sortie standard avec "
|
||||
"monitorage."
|
||||
|
||||
#: src/main/help.c:582
|
||||
#: src/main/help.c:598
|
||||
#, c-format
|
||||
msgid "Please report any bugs to: %s"
|
||||
msgstr "SVP rapporter touts bogues à %s"
|
||||
msgstr "SVP rapporter tous bogues à %s"
|
||||
|
||||
#: src/main/main.c:74
|
||||
#: src/main/main.c:230
|
||||
msgid "(input)"
|
||||
msgstr "(entrée)"
|
||||
|
||||
#: src/main/main.c:319
|
||||
msgid "state allocation failed"
|
||||
msgstr "échec de l'allocation de mémoire de condition"
|
||||
|
||||
#: src/main/options.c:173
|
||||
msgid "option structure allocation failed"
|
||||
msgstr "l'allocation pour la structure d'une option a echoué"
|
||||
|
||||
#: src/main/options.c:192
|
||||
msgid "option structure argv allocation failed"
|
||||
msgstr "l'allocation pour la structure de l'option argv a echoué"
|
||||
|
||||
#: src/main/options.c:254
|
||||
msgid "integer argument expected"
|
||||
msgstr "Valeur entière attendue"
|
||||
|
||||
#: src/main/options.c:265
|
||||
msgid "numeric argument expected"
|
||||
msgstr "Valeur numérique attendue"
|
||||
|
||||
#: src/main/options.c:276
|
||||
msgid "process ID or pid:fd pair expected"
|
||||
msgstr "ID de processus ou paire pid:fd attendue"
|
||||
|
||||
#: src/main/options.c:283
|
||||
msgid "invalid process ID"
|
||||
msgstr "ID de processus non valide"
|
||||
|
||||
#: src/main/options.c:384 src/pv/file.c:323
|
||||
#: src/main/options.c:144 src/pv/file.c:324
|
||||
msgid "failed to stat file"
|
||||
msgstr "échec à statuer sur le fichier"
|
||||
|
||||
#: src/main/options.c:487
|
||||
#: src/main/options.c:158
|
||||
msgid "is a directory"
|
||||
msgstr "est un répertoire"
|
||||
|
||||
#: src/main/options.c:187
|
||||
msgid "failed to generate sysfs filename"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:209
|
||||
msgid "failed to read sysfs size file"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:229
|
||||
msgid "failed to open block device"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:239
|
||||
msgid "failed to determine size of block device"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:344
|
||||
msgid "option structure allocation failed"
|
||||
msgstr "l'allocation pour la structure d'une option a échoué"
|
||||
|
||||
#: src/main/options.c:363
|
||||
msgid "option structure argv allocation failed"
|
||||
msgstr "l'allocation pour la structure de l'option argv a échoué"
|
||||
|
||||
#: src/main/options.c:425
|
||||
msgid "integer argument expected"
|
||||
msgstr "Valeur entière attendue"
|
||||
|
||||
#: src/main/options.c:436
|
||||
msgid "numeric argument expected"
|
||||
msgstr "Valeur numérique attendue"
|
||||
|
||||
#: src/main/options.c:447
|
||||
msgid "process ID or pid:fd pair expected"
|
||||
msgstr "ID de processus ou paire pid:fd attendue"
|
||||
|
||||
#: src/main/options.c:454
|
||||
msgid "invalid process ID"
|
||||
msgstr "ID de processus non valide"
|
||||
|
||||
#: src/main/options.c:679
|
||||
#, c-format
|
||||
msgid "Try `%s --help' for more information."
|
||||
msgstr "Essayez `%s --help' pour plus d'information."
|
||||
msgstr "Essayez `%s --help' pour plus d'informations."
|
||||
|
||||
#: src/main/options.c:489
|
||||
#: src/main/options.c:681
|
||||
#, c-format
|
||||
msgid "Try `%s -h' for more information."
|
||||
msgstr "Essayez `%s -h' pour plus d'information."
|
||||
msgstr "Essayez `%s -h' pour plus d'informations."
|
||||
|
||||
#: src/main/options.c:520
|
||||
#: src/main/options.c:712
|
||||
msgid ""
|
||||
"cannot use line mode or transfer modifier options when watching file "
|
||||
"descriptors"
|
||||
@@ -295,183 +358,207 @@ msgstr ""
|
||||
"impossible d'utiliser le mode ligne ou les options de modificateur de "
|
||||
"transfert lors de la visualisation des descripteurs de fichiers"
|
||||
|
||||
#: src/main/options.c:529
|
||||
#: src/main/options.c:721
|
||||
msgid "cannot use cursor positioning when watching file descriptors"
|
||||
msgstr ""
|
||||
"impossible d'utiliser le positionnement du curseur lors de la visualisation "
|
||||
"des descripteurs de fichier"
|
||||
|
||||
#: src/main/options.c:538
|
||||
#: src/main/options.c:730
|
||||
msgid "cannot use remote control when watching file descriptors"
|
||||
msgstr ""
|
||||
"impossible d'utiliser la télécommande lors de la visualisation des "
|
||||
"descripteurs de fichiers"
|
||||
|
||||
#: src/main/options.c:547
|
||||
#: src/main/options.c:739
|
||||
msgid "cannot transfer files when watching file descriptors"
|
||||
msgstr ""
|
||||
"impossible de transférer des fichiers lorsque vous regardez des descripteurs "
|
||||
"de fichiers"
|
||||
|
||||
#: src/main/options.c:562
|
||||
#: src/main/options.c:754
|
||||
msgid "not available on systems without /proc/self/fdinfo"
|
||||
msgstr "non disponible sur les systèmes sans /proc/self/fdinfo"
|
||||
|
||||
#: src/main/remote.c:295
|
||||
#: src/main/remote.c:304
|
||||
msgid "message not received"
|
||||
msgstr "message non reçu"
|
||||
|
||||
#: src/main/remote.c:422
|
||||
#: src/main/remote.c:431
|
||||
msgid "SA_SIGINFO not supported on this system"
|
||||
msgstr "SA_SIGINFO non pris en charge sur ce système"
|
||||
|
||||
#: src/main/version.c:28
|
||||
msgid "License: GPLv3+ <https://www.gnu.org/licenses/gpl-3.0.html>"
|
||||
msgstr ""
|
||||
msgstr "License : GPLv3+ <https://www.gnu.org/licenses/gpl-3.0.html>"
|
||||
|
||||
#: src/main/version.c:29
|
||||
msgid "This is free software: you are free to change and redistribute it."
|
||||
msgstr ""
|
||||
"Ceci est un logiciel libre : vous êtes libre de le modifier et de le "
|
||||
"redistribuer."
|
||||
|
||||
#: src/main/version.c:30
|
||||
msgid "There is NO WARRANTY, to the extent permitted by law."
|
||||
msgstr ""
|
||||
msgstr "Il n'y a AUCUNE GARANTIE, dans la mesure permise par la loi."
|
||||
|
||||
#: src/main/version.c:32
|
||||
msgid "Project web site"
|
||||
msgstr ""
|
||||
msgstr "Site web du projet"
|
||||
|
||||
#: src/pv/cursor.c:87
|
||||
#: src/pv/cursor.c:61
|
||||
msgid "failed to get terminal name"
|
||||
msgstr "échec de lecture du nom du terminal"
|
||||
|
||||
#: src/pv/cursor.c:130
|
||||
#: src/pv/cursor.c:106
|
||||
msgid "failed to open lock file"
|
||||
msgstr "échec de l'ouverture du fichier de verrouillage"
|
||||
|
||||
#: src/pv/cursor.c:163
|
||||
#: src/pv/cursor.c:139
|
||||
msgid "lock attempt failed"
|
||||
msgstr "tentative de verrouillage échoué"
|
||||
msgstr "échec de la tentative de verrouillage"
|
||||
|
||||
#: src/pv/cursor.c:424
|
||||
#: src/pv/cursor.c:400
|
||||
msgid "failed to open terminal"
|
||||
msgstr "l'ouverture du terminal a échoué"
|
||||
msgstr "échec de l'ouverture du terminal"
|
||||
|
||||
#: src/pv/display.c:192
|
||||
#: src/pv/display.c:233
|
||||
msgid "yzafpnum kMGTPEZY"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:210
|
||||
#: src/pv/display.c:251
|
||||
msgid "yzafpnum KMGTPEZY"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:746 src/pv/transfer.c:910
|
||||
#: src/pv/display.c:681 src/pv/transfer.c:1011
|
||||
msgid "buffer allocation failed"
|
||||
msgstr "l'allocation de mémoire tampon a échoué"
|
||||
msgstr "échec de l'allocation de mémoire tampon"
|
||||
|
||||
#: src/pv/display.c:845
|
||||
#: src/pv/display.c:810
|
||||
msgid "b"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:848 src/pv/transfer.c:595
|
||||
#: src/pv/display.c:813 src/pv/transfer.c:602
|
||||
msgid "B"
|
||||
msgstr "O"
|
||||
|
||||
#: src/pv/display.c:890 src/pv/display.c:907
|
||||
#: src/pv/display.c:857 src/pv/display.c:872 src/pv/display.c:1091
|
||||
#: src/pv/loop.c:549
|
||||
msgid "b/s"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:895 src/pv/display.c:912
|
||||
#: src/pv/display.c:861 src/pv/display.c:876 src/pv/display.c:1095
|
||||
msgid "/s"
|
||||
msgstr "/s"
|
||||
|
||||
#: src/pv/display.c:895 src/pv/display.c:912
|
||||
#: src/pv/display.c:861 src/pv/display.c:876 src/pv/display.c:1095
|
||||
#: src/pv/loop.c:549
|
||||
msgid "B/s"
|
||||
msgstr "O/s"
|
||||
|
||||
#: src/pv/display.c:940 src/pv/display.c:944 src/pv/display.c:1010
|
||||
#: src/pv/display.c:904 src/pv/display.c:908
|
||||
msgid "ETA"
|
||||
msgstr "ETA"
|
||||
|
||||
#: src/pv/file.c:148
|
||||
#: src/pv/display.c:974
|
||||
msgid "FIN"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/file.c:149
|
||||
msgid "failed to seek to start of output"
|
||||
msgstr "ne peut pas passer au début de la sortie"
|
||||
|
||||
#: src/pv/file.c:293
|
||||
#: src/pv/file.c:294
|
||||
msgid "failed to close file"
|
||||
msgstr "la fermeture du fichier a échoué"
|
||||
|
||||
#: src/pv/file.c:316
|
||||
#: src/pv/file.c:317
|
||||
msgid "failed to read file"
|
||||
msgstr "la lecture du fichier a échoué"
|
||||
|
||||
#: src/pv/file.c:331
|
||||
#: src/pv/file.c:332
|
||||
msgid "failed to stat output file"
|
||||
msgstr "échec à statuer sur le fichier de sortie"
|
||||
|
||||
#: src/pv/file.c:353
|
||||
#: src/pv/file.c:354
|
||||
msgid "input file is output file"
|
||||
msgstr "fichiers d'entré et de sortie sont les mêmes"
|
||||
|
||||
#: src/pv/file.c:411
|
||||
#: src/pv/file.c:412
|
||||
msgid "(none)"
|
||||
msgstr ""
|
||||
msgstr "(aucun)"
|
||||
|
||||
#: src/pv/file.c:413
|
||||
#: src/pv/file.c:414
|
||||
msgid "(stdin)"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/loop.c:570 src/pv/loop.c:621 src/pv/loop.c:662 src/pv/watchpid.c:99
|
||||
#: src/pv/loop.c:548
|
||||
msgid "rate min/avg/max/mdev"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/loop.c:560
|
||||
msgid "rate not measured"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/loop.c:767 src/pv/loop.c:818 src/pv/loop.c:859 src/pv/watchpid.c:99
|
||||
#: src/pv/watchpid.c:109 src/pv/watchpid.c:120 src/pv/watchpid.c:128
|
||||
#: src/pv/watchpid.c:165 src/pv/watchpid.c:184 src/pv/watchpid.c:192
|
||||
#: src/pv/watchpid.c:202 src/pv/watchpid.c:293 src/pv/watchpid.c:301
|
||||
#: src/pv/watchpid.c:377 src/pv/watchpid.c:398
|
||||
#: src/pv/watchpid.c:202 src/pv/watchpid.c:300 src/pv/watchpid.c:308
|
||||
#: src/pv/watchpid.c:384 src/pv/watchpid.c:405
|
||||
msgid "pid"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/state.c:36
|
||||
#: src/pv/state.c:40
|
||||
msgid "history structure allocation failed"
|
||||
msgstr ""
|
||||
msgstr "l'allocation de la structure de l'historique a échoué"
|
||||
|
||||
#: src/pv/state.c:386 src/pv/state.c:397
|
||||
#: src/pv/state.c:572 src/pv/state.c:583
|
||||
msgid "file list allocation failed"
|
||||
msgstr ""
|
||||
msgstr "échec de l'allocation de la liste de fichiers"
|
||||
|
||||
#: src/pv/transfer.c:457
|
||||
#: src/pv/transfer.c:464
|
||||
msgid "read failed"
|
||||
msgstr "la lecture a échoué"
|
||||
|
||||
#: src/pv/transfer.c:480
|
||||
#: src/pv/transfer.c:487
|
||||
msgid "warning: read errors detected"
|
||||
msgstr "avertissement: erreurs de lecture détectées"
|
||||
msgstr "avertissement : erreurs de lecture détectées"
|
||||
|
||||
#: src/pv/transfer.c:496
|
||||
#: src/pv/transfer.c:503
|
||||
msgid "file is not seekable"
|
||||
msgstr "ne peut pas se déplacer dans le fichier"
|
||||
|
||||
#: src/pv/transfer.c:574
|
||||
#: src/pv/transfer.c:581
|
||||
msgid "failed to seek past error"
|
||||
msgstr "n'a pas réussi à dépasser l'erreur"
|
||||
|
||||
#: src/pv/transfer.c:594
|
||||
#: src/pv/transfer.c:601
|
||||
msgid "skipped past read error"
|
||||
msgstr "erreur de lecture dépassée"
|
||||
|
||||
#: src/pv/transfer.c:634
|
||||
#: src/pv/transfer.c:642
|
||||
msgid "no transfer buffer allocated"
|
||||
msgstr "aucun tampon de transfert alloué"
|
||||
|
||||
#: src/pv/transfer.c:684
|
||||
msgid "failed to set interval timer"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:647
|
||||
msgid "failed to set alarm signal handler"
|
||||
#: src/pv/transfer.c:710
|
||||
msgid "failed to clear interval timer"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:774
|
||||
#: src/pv/transfer.c:740
|
||||
msgid "line position buffer allocation failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:872
|
||||
msgid "write failed"
|
||||
msgstr "l'écriture a échoué"
|
||||
|
||||
#: src/pv/transfer.c:1007
|
||||
#: src/pv/transfer.c:1109
|
||||
msgid "select call failed"
|
||||
msgstr "appel de sélection a échoué"
|
||||
msgstr "l'appel de sélection a échoué"
|
||||
|
||||
#: src/pv/watchpid.c:109 src/pv/watchpid.c:121 src/pv/watchpid.c:130
|
||||
#: src/pv/watchpid.c:184 src/pv/watchpid.c:193 src/pv/watchpid.c:204
|
||||
@@ -481,3 +568,6 @@ msgstr ""
|
||||
#: src/pv/watchpid.c:130 src/pv/watchpid.c:204
|
||||
msgid "not a regular file or block device"
|
||||
msgstr "pas un fichier ordinaire ou un périphérique de bloc"
|
||||
|
||||
#~ msgid "failed to set alarm signal handler"
|
||||
#~ msgstr "échec de la définition du gestionnaire de signal d'alarme"
|
||||
|
||||
@@ -6,14 +6,17 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: pv@ivarch.com\n"
|
||||
"POT-Creation-Date: 2023-11-19 14:19+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"POT-Creation-Date: 2024-12-02 17:56+0000\n"
|
||||
"PO-Revision-Date: 2024-10-20 14:07+0000\n"
|
||||
"Last-Translator: coralpink <coralpink@users.noreply.translate.codeberg.org>\n"
|
||||
"Language-Team: Polish <https://translate.codeberg.org/projects/pv/pv/pl/>\n"
|
||||
"Language: pl\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
|
||||
"|| n%100>=20) ? 1 : 2;\n"
|
||||
"X-Generator: Weblate 5.7.2\n"
|
||||
|
||||
#: src/main/help.c:284
|
||||
msgid "show progress bar"
|
||||
@@ -29,7 +32,7 @@ msgstr "pokaż szacowany czas ukończenia"
|
||||
|
||||
#: src/main/help.c:293
|
||||
msgid "show absolute estimated time of arrival (completion)"
|
||||
msgstr ""
|
||||
msgstr "pokaż bezwzględny szacowany czas ukończenia"
|
||||
|
||||
#: src/main/help.c:296
|
||||
msgid "show data transfer rate counter"
|
||||
@@ -37,436 +40,524 @@ msgstr "pokaż licznik prędkości przesyłania"
|
||||
|
||||
#: src/main/help.c:299
|
||||
msgid "show data transfer average rate counter"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:301 src/main/help.c:329 src/main/help.c:341
|
||||
msgid "SEC"
|
||||
msgstr "WARTOŚĆ"
|
||||
msgstr "pokaż licznik uśrednionej prędkości przesyłania"
|
||||
|
||||
#: src/main/help.c:302
|
||||
msgid "compute average rate over past SEC seconds (default 30s)"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:305
|
||||
msgid "show number of bytes transferred"
|
||||
msgstr "pokaż ilość przesłanych bajtów"
|
||||
|
||||
#: src/main/help.c:305
|
||||
msgid "show percentage of transfer buffer in use"
|
||||
msgstr "pokaż procentowe użycie bufora transferu"
|
||||
|
||||
#: src/main/help.c:307
|
||||
msgid "NUM"
|
||||
msgstr "LICZBA"
|
||||
|
||||
#: src/main/help.c:308
|
||||
msgid "show number of bits transferred"
|
||||
msgstr ""
|
||||
msgid "show NUM bytes last written"
|
||||
msgstr "pokaż ostatnie LICZBA przesłanych bajtów"
|
||||
|
||||
#: src/main/help.c:310
|
||||
msgid "FORMAT"
|
||||
msgstr "FORMAT"
|
||||
|
||||
#: src/main/help.c:311
|
||||
msgid "show percentage of transfer buffer in use"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:313
|
||||
msgid "NUM"
|
||||
msgstr ""
|
||||
msgid "set output format to FORMAT"
|
||||
msgstr "ustaw FORMAT jako format wyjściowy"
|
||||
|
||||
#: src/main/help.c:314
|
||||
msgid "show NUM bytes last written"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:316
|
||||
msgid "FORMAT"
|
||||
msgstr ""
|
||||
msgid "output percentages, not visual information"
|
||||
msgstr "wyświetl wyjście procentowo, bez graficznej prezentacji"
|
||||
|
||||
#: src/main/help.c:317
|
||||
msgid "set output format to FORMAT"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:320
|
||||
msgid "output percentages, not visual information"
|
||||
msgstr "wświetl wyjście procentowo, bez graficznej prezentacji"
|
||||
|
||||
#: src/main/help.c:323
|
||||
msgid "do not output any transfer information at all"
|
||||
msgstr "nie wyświetlaj żadnych informacji o przesyłaniu"
|
||||
|
||||
#: src/main/help.c:321
|
||||
msgid "show number of bits transferred"
|
||||
msgstr "pokaż ilość przesłanych bitów"
|
||||
|
||||
#: src/main/help.c:324
|
||||
msgid "treat suffixes as multiples of 1000 rather than 1024"
|
||||
msgstr "traktuj przyrostki jako wielokrotności 1000 zamiast 1024"
|
||||
|
||||
#: src/main/help.c:327
|
||||
msgid "display nothing until first byte transferred"
|
||||
msgstr "nie wyświetlaj nic aż do pierwszego przesłanego bajtu"
|
||||
|
||||
#: src/main/help.c:329 src/main/help.c:344 src/main/help.c:347
|
||||
msgid "SEC"
|
||||
msgstr "SEKUNDY"
|
||||
|
||||
#: src/main/help.c:330
|
||||
msgid "display nothing until SEC seconds have passed"
|
||||
msgstr ""
|
||||
msgstr "nie wyświetlaj nic do momentu upłynięcia SEKUNDY sekund"
|
||||
|
||||
#: src/main/help.c:332
|
||||
msgid "SIZE"
|
||||
msgstr "WARTOŚĆ"
|
||||
msgstr "ROZMIAR"
|
||||
|
||||
#: src/main/help.c:333
|
||||
msgid "set estimated data size to SIZE bytes"
|
||||
msgstr "ustaw oczekiwany rozmiar danych na WARTOŚĆ bajtów"
|
||||
msgstr "ustaw oczekiwany rozmiar danych na ROZMIAR bajtów"
|
||||
|
||||
#: src/main/help.c:336
|
||||
msgid "count lines instead of bytes"
|
||||
msgid "if size unknown, show rate vs max rate"
|
||||
msgstr ""
|
||||
"jeśli rozmiar nie jest znany, wyświetl zestawienie prędkości do maksymalnej "
|
||||
"prędkości"
|
||||
|
||||
#: src/main/help.c:339
|
||||
msgid "lines are null-terminated"
|
||||
msgstr ""
|
||||
msgid "count lines instead of bytes"
|
||||
msgstr "zliczaj linie zamiast bajty"
|
||||
|
||||
#: src/main/help.c:342
|
||||
msgid "update every SEC seconds"
|
||||
msgstr "aktualizuj co każde WARTOŚĆ sekund"
|
||||
|
||||
#: src/main/help.c:344
|
||||
msgid "WIDTH"
|
||||
msgstr "WARTOŚĆ"
|
||||
msgid "lines are null-terminated"
|
||||
msgstr "linie są zakończone znakiem NUL"
|
||||
|
||||
#: src/main/help.c:345
|
||||
msgid "assume terminal is WIDTH characters wide"
|
||||
msgstr "przyjmij, że terminal ma szerokość WARTOŚĆ znaków"
|
||||
|
||||
#: src/main/help.c:347
|
||||
msgid "HEIGHT"
|
||||
msgstr ""
|
||||
msgid "update every SEC seconds"
|
||||
msgstr "aktualizuj co każde SEKUNDY sekund"
|
||||
|
||||
#: src/main/help.c:348
|
||||
msgid "assume terminal is HEIGHT rows high"
|
||||
msgstr "przyjmij, że terminal ma szerokość WARTOŚĆ znaków"
|
||||
msgid "compute average rate over past SEC seconds (default 30s)"
|
||||
msgstr ""
|
||||
"oblicz średnią prędkość transferu na podstawie poprzednich SEKUNDY sekund "
|
||||
"(domyślnie 30 s)"
|
||||
|
||||
#: src/main/help.c:350
|
||||
msgid "WIDTH"
|
||||
msgstr "SZEROKOŚĆ"
|
||||
|
||||
#: src/main/help.c:351
|
||||
msgid "assume terminal is WIDTH characters wide"
|
||||
msgstr "przyjmij, że terminal ma szerokość SZEROKOŚĆ znaków"
|
||||
|
||||
#: src/main/help.c:353
|
||||
msgid "HEIGHT"
|
||||
msgstr "WYSOKOŚĆ"
|
||||
|
||||
#: src/main/help.c:354
|
||||
msgid "assume terminal is HEIGHT rows high"
|
||||
msgstr "przyjmij, że terminal ma wysokość WYSOKOŚĆ linii"
|
||||
|
||||
#: src/main/help.c:356
|
||||
msgid "NAME"
|
||||
msgstr "NAZWA"
|
||||
|
||||
#: src/main/help.c:351
|
||||
#: src/main/help.c:357
|
||||
msgid "prefix visual information with NAME"
|
||||
msgstr "poprzedź informacje prefiksem NAZWA"
|
||||
|
||||
#: src/main/help.c:354
|
||||
msgid "output even if standard error is not a terminal"
|
||||
msgstr "pokaż wyjście nawet gdy błędy nie są typu terminal"
|
||||
|
||||
#: src/main/help.c:357
|
||||
msgid "use cursor positioning escape sequences"
|
||||
msgstr "używaj sekwencji escape do pozycjonowania"
|
||||
#: src/main/help.c:359
|
||||
msgid "SPEC"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:360
|
||||
msgid "RATE"
|
||||
msgid "also send progress to SPEC"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:361
|
||||
msgid "limit transfer to RATE bytes per second"
|
||||
msgstr "ogranicz przesyłane dane do RATE bajtów na sekundę"
|
||||
#: src/main/help.c:363
|
||||
msgid "output transfer statistics at the end"
|
||||
msgstr "wyświetl na końcu statystyki transferu"
|
||||
|
||||
#: src/main/help.c:363 src/main/help.c:372
|
||||
msgid "BYTES"
|
||||
msgstr ""
|
||||
#: src/main/help.c:366
|
||||
msgid "output even if standard error is not a terminal"
|
||||
msgstr "pokaż wyjście nawet standardowe wyjście błędu nie jest terminalem"
|
||||
|
||||
#: src/main/help.c:364
|
||||
msgid "use a buffer size of BYTES"
|
||||
msgstr ""
|
||||
#: src/main/help.c:369
|
||||
msgid "use cursor positioning escape sequences"
|
||||
msgstr "używaj znaków ucieczki do pozycjonowania kursora"
|
||||
|
||||
#: src/main/help.c:367
|
||||
msgid "never use splice(), always use read/write"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:370
|
||||
msgid "skip read errors in input"
|
||||
msgstr ""
|
||||
#: src/main/help.c:372 src/main/help.c:402 src/main/help.c:414
|
||||
#: src/main/help.c:424
|
||||
msgid "FILE"
|
||||
msgstr "PLIK"
|
||||
|
||||
#: src/main/help.c:373
|
||||
msgid "skip errors in BYTES blocks at a time"
|
||||
msgstr ""
|
||||
msgid "write output to FILE instead of stdout"
|
||||
msgstr "zapisz wyjście do PLIK zamiast do wyjścia standardowego"
|
||||
|
||||
#: src/main/help.c:375
|
||||
msgid "RATE"
|
||||
msgstr "PRĘDKOŚĆ"
|
||||
|
||||
#: src/main/help.c:376
|
||||
msgid "stop after --size bytes have been transferred"
|
||||
msgstr ""
|
||||
msgid "limit transfer to RATE bytes per second"
|
||||
msgstr "ogranicz przesyłane dane do PRĘDKOŚĆ bajtów na sekundę"
|
||||
|
||||
#: src/main/help.c:378 src/main/help.c:387
|
||||
msgid "BYTES"
|
||||
msgstr "BAJTY"
|
||||
|
||||
#: src/main/help.c:379
|
||||
msgid "flush cache to disk after every write"
|
||||
msgstr ""
|
||||
msgid "use a buffer size of BYTES"
|
||||
msgstr "użyj bufora o rozmiarze BAJTY"
|
||||
|
||||
#: src/main/help.c:382
|
||||
msgid "use direct I/O to bypass cache"
|
||||
msgstr ""
|
||||
msgid "never use splice(), always use read/write"
|
||||
msgstr "nigdy nie używaj splice(), zawsze używaj read/write"
|
||||
|
||||
#: src/main/help.c:385
|
||||
msgid "discard input instead of writing to output"
|
||||
msgstr ""
|
||||
msgid "skip read errors in input"
|
||||
msgstr "pomijaj błędy odczytu wejścia"
|
||||
|
||||
#: src/main/help.c:388
|
||||
msgid "PID"
|
||||
msgstr ""
|
||||
msgid "skip errors in BYTES blocks at a time"
|
||||
msgstr "pomijaj błędy w blokach po BAJTY bajtów na raz"
|
||||
|
||||
#: src/main/help.c:389
|
||||
msgid "update settings of process PID"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:393 src/main/help.c:408
|
||||
msgid "FILE"
|
||||
msgstr ""
|
||||
#: src/main/help.c:391
|
||||
msgid "stop after --size bytes have been transferred"
|
||||
msgstr "zakończ po przesłaniu --size bajtów"
|
||||
|
||||
#: src/main/help.c:394
|
||||
msgid "save process ID in FILE"
|
||||
msgstr ""
|
||||
msgid "flush cache to disk after every write"
|
||||
msgstr "wymuś zapis pamięci podręcznej na dysk po każdym zapisie"
|
||||
|
||||
#: src/main/help.c:397
|
||||
msgid "use direct I/O to bypass cache"
|
||||
msgstr ""
|
||||
"użyj bezpośredniego wejścia/wyjścia celem pominięcia pamięci podręcznej"
|
||||
|
||||
#: src/main/help.c:400
|
||||
msgid "discard input instead of writing to output"
|
||||
msgstr "zignoruj dane wejściowe zamiast wyświetlić je na wyjściu standardowym"
|
||||
|
||||
#: src/main/help.c:403
|
||||
msgid "write all input to FILE before writing to output"
|
||||
msgstr ""
|
||||
"zapisz wszystkie dane wejściowe do PLIK przed wyświetleniem ich na wyjściu"
|
||||
|
||||
#: src/main/help.c:405
|
||||
msgid "PID[:FD]"
|
||||
msgstr ""
|
||||
msgstr "PID[:FD]"
|
||||
|
||||
#: src/main/help.c:398
|
||||
#: src/main/help.c:406
|
||||
msgid "watch file FD opened by process PID"
|
||||
msgstr ""
|
||||
msgstr "obserwuj plik FD otworzony przez proces PID"
|
||||
|
||||
#: src/main/help.c:402
|
||||
#: src/main/help.c:409
|
||||
msgid "PID"
|
||||
msgstr "PID"
|
||||
|
||||
#: src/main/help.c:410
|
||||
msgid "update settings of process PID"
|
||||
msgstr "zaktualizuj ustawienia procesu PID"
|
||||
|
||||
#: src/main/help.c:415
|
||||
msgid "save process ID in FILE"
|
||||
msgstr "zapisz ID procesu do PLIK"
|
||||
|
||||
#: src/main/help.c:418
|
||||
msgid "show this help and exit"
|
||||
msgstr "wyświetl te informacje z pomocą i wyjdź"
|
||||
|
||||
#: src/main/help.c:405
|
||||
#: src/main/help.c:421
|
||||
msgid "show version information and exit"
|
||||
msgstr "wyświetl informacje o wersji i wyjdź"
|
||||
|
||||
#: src/main/help.c:409
|
||||
#: src/main/help.c:425
|
||||
msgid "write debug logs to FILE"
|
||||
msgstr ""
|
||||
msgstr "zapisz logi debugujące do PLIK"
|
||||
|
||||
#: src/main/help.c:434
|
||||
#: src/main/help.c:450
|
||||
#, c-format
|
||||
msgid "Usage: %s [OPTION] [FILE]..."
|
||||
msgstr "Sposób użycia: %s [OPCJA] [PLIK]..."
|
||||
|
||||
#: src/main/help.c:445
|
||||
#: src/main/help.c:461
|
||||
msgid ""
|
||||
"Concatenate FILE(s), or standard input, to standard output, with monitoring."
|
||||
msgstr ""
|
||||
"Łączenie PLIK(ów) lub wejścia standardowego, do wyjścia standardowego z "
|
||||
"monitoringiem."
|
||||
|
||||
#: src/main/help.c:582
|
||||
#: src/main/help.c:598
|
||||
#, c-format
|
||||
msgid "Please report any bugs to: %s"
|
||||
msgstr "Proszę przesyłać zgłoszenia błędów do %s"
|
||||
|
||||
#: src/main/main.c:74
|
||||
#: src/main/main.c:230
|
||||
msgid "(input)"
|
||||
msgstr "(wejście)"
|
||||
|
||||
#: src/main/main.c:319
|
||||
msgid "state allocation failed"
|
||||
msgstr ""
|
||||
msgstr "alokacja stanu programu nie powiodła się"
|
||||
|
||||
#: src/main/options.c:173
|
||||
msgid "option structure allocation failed"
|
||||
msgstr "nie udało się zaalokować struktur opcji"
|
||||
|
||||
#: src/main/options.c:192
|
||||
msgid "option structure argv allocation failed"
|
||||
msgstr "nie udało się zaalokować struktur opcji argv"
|
||||
|
||||
#: src/main/options.c:254
|
||||
msgid "integer argument expected"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:265
|
||||
msgid "numeric argument expected"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:276
|
||||
msgid "process ID or pid:fd pair expected"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:283
|
||||
msgid "invalid process ID"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:384 src/pv/file.c:323
|
||||
#: src/main/options.c:144 src/pv/file.c:324
|
||||
msgid "failed to stat file"
|
||||
msgstr "nie udało się wykonać operacji stat na pliku"
|
||||
|
||||
#: src/main/options.c:487
|
||||
#: src/main/options.c:158
|
||||
msgid "is a directory"
|
||||
msgstr "jest katalogiem"
|
||||
|
||||
#: src/main/options.c:187
|
||||
msgid "failed to generate sysfs filename"
|
||||
msgstr "nie udało się wygenerować nazwy pliku dla sysfs"
|
||||
|
||||
#: src/main/options.c:209
|
||||
msgid "failed to read sysfs size file"
|
||||
msgstr "nie udało się odczytać rozmiaru pliku sysfs"
|
||||
|
||||
#: src/main/options.c:229
|
||||
msgid "failed to open block device"
|
||||
msgstr "nie udało się otworzyć urządzenia blokowego"
|
||||
|
||||
#: src/main/options.c:239
|
||||
msgid "failed to determine size of block device"
|
||||
msgstr "nie udało się ustalić rozmiaru urządzenia blokowego"
|
||||
|
||||
#: src/main/options.c:344
|
||||
msgid "option structure allocation failed"
|
||||
msgstr "nie udało się zaalokować struktur opcji"
|
||||
|
||||
#: src/main/options.c:363
|
||||
msgid "option structure argv allocation failed"
|
||||
msgstr "nie udało się zaalokować struktur opcji argv"
|
||||
|
||||
#: src/main/options.c:425
|
||||
msgid "integer argument expected"
|
||||
msgstr "oczekiwany argument typu liczby całkowitej"
|
||||
|
||||
#: src/main/options.c:436
|
||||
msgid "numeric argument expected"
|
||||
msgstr "oczekiwany argument liczbowy"
|
||||
|
||||
#: src/main/options.c:447
|
||||
msgid "process ID or pid:fd pair expected"
|
||||
msgstr "oczekiwany proces ID lub para PID:FD"
|
||||
|
||||
#: src/main/options.c:454
|
||||
msgid "invalid process ID"
|
||||
msgstr "niepoprawne ID procesu"
|
||||
|
||||
#: src/main/options.c:679
|
||||
#, c-format
|
||||
msgid "Try `%s --help' for more information."
|
||||
msgstr "Spróbuj `%s --help' by uzyskać więcej informacji"
|
||||
msgstr "Spróbuj `%s --help' by uzyskać więcej informacji."
|
||||
|
||||
#: src/main/options.c:489
|
||||
#: src/main/options.c:681
|
||||
#, c-format
|
||||
msgid "Try `%s -h' for more information."
|
||||
msgstr "Spróbuj `%s -h' by uzyskać więcej informacji"
|
||||
msgstr "Spróbuj `%s -h' by uzyskać więcej informacji."
|
||||
|
||||
#: src/main/options.c:520
|
||||
#: src/main/options.c:712
|
||||
msgid ""
|
||||
"cannot use line mode or transfer modifier options when watching file "
|
||||
"descriptors"
|
||||
msgstr ""
|
||||
"nie można użyć trybu zliczania linii lub opcji modyfikujących przesył "
|
||||
"łącznie z opcją obserwowania deskryptorów plików"
|
||||
|
||||
#: src/main/options.c:529
|
||||
#: src/main/options.c:721
|
||||
msgid "cannot use cursor positioning when watching file descriptors"
|
||||
msgstr ""
|
||||
"nie można użyć pozycjonowania kursora łącznie z opcją obserwowania "
|
||||
"deskryptorów plików"
|
||||
|
||||
#: src/main/options.c:538
|
||||
#: src/main/options.c:730
|
||||
msgid "cannot use remote control when watching file descriptors"
|
||||
msgstr ""
|
||||
"nie można użyć opcji zaktualizowania ustawień procesu łącznie z opcją "
|
||||
"obserwowania deskryptorów plików"
|
||||
|
||||
#: src/main/options.c:547
|
||||
#: src/main/options.c:739
|
||||
msgid "cannot transfer files when watching file descriptors"
|
||||
msgstr ""
|
||||
msgstr "nie można przesyłać plików z opcją obserwowania deskryptorów plików"
|
||||
|
||||
#: src/main/options.c:562
|
||||
#: src/main/options.c:754
|
||||
msgid "not available on systems without /proc/self/fdinfo"
|
||||
msgstr ""
|
||||
msgstr "niedostępne na systemach bez /proc/self/fdinfo"
|
||||
|
||||
#: src/main/remote.c:295
|
||||
#: src/main/remote.c:304
|
||||
msgid "message not received"
|
||||
msgstr ""
|
||||
msgstr "wiadomość nieodebrana"
|
||||
|
||||
#: src/main/remote.c:422
|
||||
#: src/main/remote.c:431
|
||||
msgid "SA_SIGINFO not supported on this system"
|
||||
msgstr ""
|
||||
msgstr "SA_SIGINFO nie jest wspierane na tym systemie"
|
||||
|
||||
#: src/main/version.c:28
|
||||
msgid "License: GPLv3+ <https://www.gnu.org/licenses/gpl-3.0.html>"
|
||||
msgstr ""
|
||||
msgstr "Licencja: GPLv3+ <https://www.gnu.org/licenses/gpl-3.0.html>"
|
||||
|
||||
#: src/main/version.c:29
|
||||
msgid "This is free software: you are free to change and redistribute it."
|
||||
msgstr ""
|
||||
msgstr "To jest wolne oprogramowanie: masz prawo do zmian i redystrybucji."
|
||||
|
||||
#: src/main/version.c:30
|
||||
msgid "There is NO WARRANTY, to the extent permitted by law."
|
||||
msgstr ""
|
||||
msgstr "Nie udziela się GWARANCJI w zakresie dozwolonym przez prawo."
|
||||
|
||||
#: src/main/version.c:32
|
||||
msgid "Project web site"
|
||||
msgstr ""
|
||||
msgstr "Strona projektu"
|
||||
|
||||
#: src/pv/cursor.c:87
|
||||
#: src/pv/cursor.c:61
|
||||
msgid "failed to get terminal name"
|
||||
msgstr ""
|
||||
msgstr "nie udało się uzyskać nazwy terminala"
|
||||
|
||||
# "Przewidywany czas ukończenia" for ETA is too long
|
||||
#: src/pv/cursor.c:130
|
||||
#: src/pv/cursor.c:106
|
||||
msgid "failed to open lock file"
|
||||
msgstr ""
|
||||
msgstr "nie udało się otworzyć pliku blokowania zasobów"
|
||||
|
||||
#: src/pv/cursor.c:163
|
||||
#: src/pv/cursor.c:139
|
||||
msgid "lock attempt failed"
|
||||
msgstr ""
|
||||
msgstr "blokada zasobów nie powiodła się"
|
||||
|
||||
#: src/pv/cursor.c:424
|
||||
#: src/pv/cursor.c:400
|
||||
msgid "failed to open terminal"
|
||||
msgstr "nie udało się otworzyć terminala"
|
||||
|
||||
#: src/pv/display.c:192
|
||||
#: src/pv/display.c:233
|
||||
msgid "yzafpnum kMGTPEZY"
|
||||
msgstr ""
|
||||
msgstr "yzafpnum kMGTPEZY"
|
||||
|
||||
#: src/pv/display.c:210
|
||||
#: src/pv/display.c:251
|
||||
msgid "yzafpnum KMGTPEZY"
|
||||
msgstr ""
|
||||
msgstr "yzafpnum KMGTPEZY"
|
||||
|
||||
#: src/pv/display.c:746 src/pv/transfer.c:910
|
||||
#: src/pv/display.c:681 src/pv/transfer.c:1011
|
||||
msgid "buffer allocation failed"
|
||||
msgstr "nie udało się zaalokować bufora"
|
||||
|
||||
#: src/pv/display.c:845
|
||||
#: src/pv/display.c:810
|
||||
msgid "b"
|
||||
msgstr ""
|
||||
msgstr "b"
|
||||
|
||||
#: src/pv/display.c:848 src/pv/transfer.c:595
|
||||
#: src/pv/display.c:813 src/pv/transfer.c:602
|
||||
msgid "B"
|
||||
msgstr "B"
|
||||
|
||||
#: src/pv/display.c:890 src/pv/display.c:907
|
||||
#: src/pv/display.c:857 src/pv/display.c:872 src/pv/display.c:1091
|
||||
#: src/pv/loop.c:549
|
||||
msgid "b/s"
|
||||
msgstr ""
|
||||
msgstr "b/s"
|
||||
|
||||
#: src/pv/display.c:895 src/pv/display.c:912
|
||||
#: src/pv/display.c:861 src/pv/display.c:876 src/pv/display.c:1095
|
||||
msgid "/s"
|
||||
msgstr "/s"
|
||||
|
||||
#: src/pv/display.c:895 src/pv/display.c:912
|
||||
#: src/pv/display.c:861 src/pv/display.c:876 src/pv/display.c:1095
|
||||
#: src/pv/loop.c:549
|
||||
msgid "B/s"
|
||||
msgstr "B/s"
|
||||
|
||||
#: src/pv/display.c:940 src/pv/display.c:944 src/pv/display.c:1010
|
||||
#: src/pv/display.c:904 src/pv/display.c:908
|
||||
msgid "ETA"
|
||||
msgstr "ETA"
|
||||
|
||||
#: src/pv/file.c:148
|
||||
#: src/pv/display.c:974
|
||||
msgid "FIN"
|
||||
msgstr "FIN"
|
||||
|
||||
#: src/pv/file.c:149
|
||||
msgid "failed to seek to start of output"
|
||||
msgstr ""
|
||||
msgstr "nie udało się przewinąć wyjścia do początku"
|
||||
|
||||
# "Przewidywany czas ukończenia" for ETA is too long
|
||||
#: src/pv/file.c:293
|
||||
#: src/pv/file.c:294
|
||||
msgid "failed to close file"
|
||||
msgstr "nie udało się zamknąć pliku"
|
||||
|
||||
#: src/pv/file.c:316
|
||||
#: src/pv/file.c:317
|
||||
msgid "failed to read file"
|
||||
msgstr "nie udało się odczytać pliku"
|
||||
|
||||
#: src/pv/file.c:331
|
||||
#: src/pv/file.c:332
|
||||
msgid "failed to stat output file"
|
||||
msgstr "nie udało się wykonać operacji stat na pliku wyjściowym"
|
||||
|
||||
#: src/pv/file.c:353
|
||||
#: src/pv/file.c:354
|
||||
msgid "input file is output file"
|
||||
msgstr "plik wejściowy jest zarazem plikiem wyjściowym"
|
||||
|
||||
#: src/pv/file.c:411
|
||||
#: src/pv/file.c:412
|
||||
msgid "(none)"
|
||||
msgstr ""
|
||||
msgstr "(brak)"
|
||||
|
||||
#: src/pv/file.c:413
|
||||
#: src/pv/file.c:414
|
||||
msgid "(stdin)"
|
||||
msgstr ""
|
||||
msgstr "(stdin)"
|
||||
|
||||
#: src/pv/loop.c:570 src/pv/loop.c:621 src/pv/loop.c:662 src/pv/watchpid.c:99
|
||||
#: src/pv/loop.c:548
|
||||
msgid "rate min/avg/max/mdev"
|
||||
msgstr "prędkość min/śr/max/odch"
|
||||
|
||||
#: src/pv/loop.c:560
|
||||
msgid "rate not measured"
|
||||
msgstr "prędkość niezmierzona"
|
||||
|
||||
#: src/pv/loop.c:767 src/pv/loop.c:818 src/pv/loop.c:859 src/pv/watchpid.c:99
|
||||
#: src/pv/watchpid.c:109 src/pv/watchpid.c:120 src/pv/watchpid.c:128
|
||||
#: src/pv/watchpid.c:165 src/pv/watchpid.c:184 src/pv/watchpid.c:192
|
||||
#: src/pv/watchpid.c:202 src/pv/watchpid.c:293 src/pv/watchpid.c:301
|
||||
#: src/pv/watchpid.c:377 src/pv/watchpid.c:398
|
||||
#: src/pv/watchpid.c:202 src/pv/watchpid.c:300 src/pv/watchpid.c:308
|
||||
#: src/pv/watchpid.c:384 src/pv/watchpid.c:405
|
||||
msgid "pid"
|
||||
msgstr ""
|
||||
msgstr "pid"
|
||||
|
||||
#: src/pv/state.c:36
|
||||
#: src/pv/state.c:40
|
||||
msgid "history structure allocation failed"
|
||||
msgstr ""
|
||||
msgstr "nie udało się zaalokować struktury historii"
|
||||
|
||||
#: src/pv/state.c:386 src/pv/state.c:397
|
||||
#: src/pv/state.c:572 src/pv/state.c:583
|
||||
msgid "file list allocation failed"
|
||||
msgstr ""
|
||||
msgstr "nie udało się zaalokować listy plików"
|
||||
|
||||
#: src/pv/transfer.c:457
|
||||
#: src/pv/transfer.c:464
|
||||
msgid "read failed"
|
||||
msgstr "błąd odczytu"
|
||||
|
||||
#: src/pv/transfer.c:480
|
||||
#: src/pv/transfer.c:487
|
||||
msgid "warning: read errors detected"
|
||||
msgstr ""
|
||||
msgstr "ostrzeżenie: błędy odczytu wykryte"
|
||||
|
||||
#: src/pv/transfer.c:496
|
||||
#: src/pv/transfer.c:503
|
||||
msgid "file is not seekable"
|
||||
msgstr ""
|
||||
msgstr "pliku nie da się przewijać"
|
||||
|
||||
#: src/pv/transfer.c:574
|
||||
#: src/pv/transfer.c:581
|
||||
msgid "failed to seek past error"
|
||||
msgstr ""
|
||||
msgstr "nie udało się przewinąć za błąd"
|
||||
|
||||
#: src/pv/transfer.c:594
|
||||
#: src/pv/transfer.c:601
|
||||
msgid "skipped past read error"
|
||||
msgstr ""
|
||||
msgstr "pominięto błąd odczytu"
|
||||
|
||||
#: src/pv/transfer.c:634
|
||||
#: src/pv/transfer.c:642
|
||||
msgid "no transfer buffer allocated"
|
||||
msgstr ""
|
||||
msgstr "brak zaalokowanego bufora transferu"
|
||||
|
||||
#: src/pv/transfer.c:647
|
||||
msgid "failed to set alarm signal handler"
|
||||
msgstr ""
|
||||
#: src/pv/transfer.c:684
|
||||
msgid "failed to set interval timer"
|
||||
msgstr "nie udało się ustawić interwału czasowego"
|
||||
|
||||
#: src/pv/transfer.c:774
|
||||
# "Przewidywany czas ukończenia" for ETA is too long
|
||||
#: src/pv/transfer.c:710
|
||||
msgid "failed to clear interval timer"
|
||||
msgstr "nie udało się wyczyścić interwału czasowego"
|
||||
|
||||
#: src/pv/transfer.c:740
|
||||
msgid "line position buffer allocation failed"
|
||||
msgstr "alokacja buforu pozycji linii nie powiodła się"
|
||||
|
||||
#: src/pv/transfer.c:872
|
||||
msgid "write failed"
|
||||
msgstr "błąd zapisu"
|
||||
|
||||
#: src/pv/transfer.c:1007
|
||||
#: src/pv/transfer.c:1109
|
||||
msgid "select call failed"
|
||||
msgstr "nie udało się wywołać funkcji select"
|
||||
|
||||
#: src/pv/watchpid.c:109 src/pv/watchpid.c:121 src/pv/watchpid.c:130
|
||||
#: src/pv/watchpid.c:184 src/pv/watchpid.c:193 src/pv/watchpid.c:204
|
||||
msgid "fd"
|
||||
msgstr ""
|
||||
msgstr "fd"
|
||||
|
||||
#: src/pv/watchpid.c:130 src/pv/watchpid.c:204
|
||||
msgid "not a regular file or block device"
|
||||
msgstr ""
|
||||
msgstr "plik nie jest plikiem regularnym lub urządzeniem blokowym"
|
||||
|
||||
@@ -6,7 +6,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: pv@ivarch.com\n"
|
||||
"POT-Creation-Date: 2023-11-19 14:19+0000\n"
|
||||
"POT-Creation-Date: 2024-12-02 17:56+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@@ -39,54 +39,54 @@ msgstr "exibe a taxa de transferência"
|
||||
msgid "show data transfer average rate counter"
|
||||
msgstr "exibe o contador da taxa média de transferência de dados"
|
||||
|
||||
#: src/main/help.c:301 src/main/help.c:329 src/main/help.c:341
|
||||
msgid "SEC"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:302
|
||||
msgid "compute average rate over past SEC seconds (default 30s)"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:305
|
||||
msgid "show number of bytes transferred"
|
||||
msgstr "exibe a quantidade de bytes transferidos"
|
||||
|
||||
#: src/main/help.c:308
|
||||
msgid "show number of bits transferred"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:311
|
||||
#: src/main/help.c:305
|
||||
msgid "show percentage of transfer buffer in use"
|
||||
msgstr "exibe a porcentagem de buffer de transferência em uso"
|
||||
|
||||
#: src/main/help.c:313
|
||||
#: src/main/help.c:307
|
||||
msgid "NUM"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:314
|
||||
#: src/main/help.c:308
|
||||
msgid "show NUM bytes last written"
|
||||
msgstr "exibe NUM bytes gravados pela última vez"
|
||||
|
||||
#: src/main/help.c:316
|
||||
#: src/main/help.c:310
|
||||
msgid "FORMAT"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:317
|
||||
#: src/main/help.c:311
|
||||
msgid "set output format to FORMAT"
|
||||
msgstr "definir o formato de saída para FORMAT"
|
||||
|
||||
#: src/main/help.c:320
|
||||
#: src/main/help.c:314
|
||||
msgid "output percentages, not visual information"
|
||||
msgstr "exibe apenas as porcentagens, sem informações visuais"
|
||||
|
||||
#: src/main/help.c:323
|
||||
#: src/main/help.c:317
|
||||
msgid "do not output any transfer information at all"
|
||||
msgstr "executa programa sem exibir quaisquer informações"
|
||||
|
||||
#: src/main/help.c:321
|
||||
msgid "show number of bits transferred"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:324
|
||||
msgid "treat suffixes as multiples of 1000 rather than 1024"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:327
|
||||
msgid "display nothing until first byte transferred"
|
||||
msgstr "não exibe nada até iniciar o processamento"
|
||||
|
||||
#: src/main/help.c:329 src/main/help.c:344 src/main/help.c:347
|
||||
msgid "SEC"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:330
|
||||
msgid "display nothing until SEC seconds have passed"
|
||||
msgstr "não exibir nada até que os segundos SEC tenham passado"
|
||||
@@ -100,189 +100,242 @@ msgid "set estimated data size to SIZE bytes"
|
||||
msgstr "seta a quantidade estimada de dados em SIZE bytes"
|
||||
|
||||
#: src/main/help.c:336
|
||||
msgid "if size unknown, show rate vs max rate"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:339
|
||||
msgid "count lines instead of bytes"
|
||||
msgstr "contar linhas em vez de bytes"
|
||||
|
||||
#: src/main/help.c:339
|
||||
#: src/main/help.c:342
|
||||
msgid "lines are null-terminated"
|
||||
msgstr "linhas são terminadas em nulo"
|
||||
|
||||
#: src/main/help.c:342
|
||||
#: src/main/help.c:345
|
||||
msgid "update every SEC seconds"
|
||||
msgstr "atualiza informações a cada SEC segundos"
|
||||
|
||||
#: src/main/help.c:344
|
||||
#: src/main/help.c:348
|
||||
msgid "compute average rate over past SEC seconds (default 30s)"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:350
|
||||
msgid "WIDTH"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:345
|
||||
#: src/main/help.c:351
|
||||
msgid "assume terminal is WIDTH characters wide"
|
||||
msgstr "presuma que o terminal tem WIDTH caracteres de largura"
|
||||
|
||||
#: src/main/help.c:347
|
||||
#: src/main/help.c:353
|
||||
msgid "HEIGHT"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:348
|
||||
#: src/main/help.c:354
|
||||
msgid "assume terminal is HEIGHT rows high"
|
||||
msgstr "presuma que o terminal tem HEIGHT caracteres de altura"
|
||||
|
||||
#: src/main/help.c:350
|
||||
#: src/main/help.c:356
|
||||
msgid "NAME"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:351
|
||||
#: src/main/help.c:357
|
||||
msgid "prefix visual information with NAME"
|
||||
msgstr "exibe NAME antes das demais informações"
|
||||
|
||||
#: src/main/help.c:354
|
||||
#: src/main/help.c:359
|
||||
msgid "SPEC"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:360
|
||||
msgid "also send progress to SPEC"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:363
|
||||
msgid "output transfer statistics at the end"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:366
|
||||
msgid "output even if standard error is not a terminal"
|
||||
msgstr "gera dados mesmo que a saída de erro seja redirecionada"
|
||||
|
||||
#: src/main/help.c:357
|
||||
#: src/main/help.c:369
|
||||
msgid "use cursor positioning escape sequences"
|
||||
msgstr "utiliza caracteres de escape para posicionar o cursor"
|
||||
|
||||
#: src/main/help.c:360
|
||||
msgid "RATE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:361
|
||||
msgid "limit transfer to RATE bytes per second"
|
||||
msgstr "limita a transferência a RATE bytes por segundo"
|
||||
|
||||
#: src/main/help.c:363 src/main/help.c:372
|
||||
msgid "BYTES"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:364
|
||||
msgid "use a buffer size of BYTES"
|
||||
msgstr "use um tamanho de buffer de BYTES"
|
||||
|
||||
#: src/main/help.c:367
|
||||
msgid "never use splice(), always use read/write"
|
||||
msgstr "nunca use splice(), sempre use read/write"
|
||||
|
||||
#: src/main/help.c:370
|
||||
msgid "skip read errors in input"
|
||||
msgstr "ignorar erros de leitura em entrada"
|
||||
|
||||
#: src/main/help.c:373
|
||||
msgid "skip errors in BYTES blocks at a time"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:376
|
||||
msgid "stop after --size bytes have been transferred"
|
||||
msgstr "parar após --size bytes terem sido transferidos"
|
||||
|
||||
#: src/main/help.c:379
|
||||
msgid "flush cache to disk after every write"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:382
|
||||
msgid "use direct I/O to bypass cache"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:385
|
||||
msgid "discard input instead of writing to output"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:388
|
||||
msgid "PID"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:389
|
||||
msgid "update settings of process PID"
|
||||
msgstr "atualizar as configurações do processo PID"
|
||||
|
||||
#: src/main/help.c:393 src/main/help.c:408
|
||||
#: src/main/help.c:372 src/main/help.c:402 src/main/help.c:414
|
||||
#: src/main/help.c:424
|
||||
msgid "FILE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:373
|
||||
msgid "write output to FILE instead of stdout"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:375
|
||||
msgid "RATE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:376
|
||||
msgid "limit transfer to RATE bytes per second"
|
||||
msgstr "limita a transferência a RATE bytes por segundo"
|
||||
|
||||
#: src/main/help.c:378 src/main/help.c:387
|
||||
msgid "BYTES"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:379
|
||||
msgid "use a buffer size of BYTES"
|
||||
msgstr "use um tamanho de buffer de BYTES"
|
||||
|
||||
#: src/main/help.c:382
|
||||
msgid "never use splice(), always use read/write"
|
||||
msgstr "nunca use splice(), sempre use read/write"
|
||||
|
||||
#: src/main/help.c:385
|
||||
msgid "skip read errors in input"
|
||||
msgstr "ignorar erros de leitura em entrada"
|
||||
|
||||
#: src/main/help.c:388
|
||||
msgid "skip errors in BYTES blocks at a time"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:391
|
||||
msgid "stop after --size bytes have been transferred"
|
||||
msgstr "parar após --size bytes terem sido transferidos"
|
||||
|
||||
#: src/main/help.c:394
|
||||
msgid "save process ID in FILE"
|
||||
msgstr "salvar ID do processo em FILE"
|
||||
msgid "flush cache to disk after every write"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:397
|
||||
msgid "use direct I/O to bypass cache"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:400
|
||||
msgid "discard input instead of writing to output"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:403
|
||||
msgid "write all input to FILE before writing to output"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:405
|
||||
msgid "PID[:FD]"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:398
|
||||
#: src/main/help.c:406
|
||||
msgid "watch file FD opened by process PID"
|
||||
msgstr "assistir arquivo FD aberto pelo processo PID"
|
||||
|
||||
#: src/main/help.c:402
|
||||
#: src/main/help.c:409
|
||||
msgid "PID"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:410
|
||||
msgid "update settings of process PID"
|
||||
msgstr "atualizar as configurações do processo PID"
|
||||
|
||||
#: src/main/help.c:415
|
||||
msgid "save process ID in FILE"
|
||||
msgstr "salvar ID do processo em FILE"
|
||||
|
||||
#: src/main/help.c:418
|
||||
msgid "show this help and exit"
|
||||
msgstr "exibe esta tela de ajuda e termina"
|
||||
|
||||
#: src/main/help.c:405
|
||||
#: src/main/help.c:421
|
||||
msgid "show version information and exit"
|
||||
msgstr "exibe a versão e termina"
|
||||
|
||||
#: src/main/help.c:409
|
||||
#: src/main/help.c:425
|
||||
msgid "write debug logs to FILE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:434
|
||||
#: src/main/help.c:450
|
||||
#, c-format
|
||||
msgid "Usage: %s [OPTION] [FILE]..."
|
||||
msgstr "Uso: %s [OPÇÕES] [ARQUIVOS]..."
|
||||
|
||||
#: src/main/help.c:445
|
||||
#: src/main/help.c:461
|
||||
msgid ""
|
||||
"Concatenate FILE(s), or standard input, to standard output, with monitoring."
|
||||
msgstr ""
|
||||
"Concatena ARQUIVO(s) ou a entrada padrão e grava na saída padrão, com "
|
||||
"monitoramento."
|
||||
|
||||
#: src/main/help.c:582
|
||||
#: src/main/help.c:598
|
||||
#, c-format
|
||||
msgid "Please report any bugs to: %s"
|
||||
msgstr "Por favor, reporte quaisquer defeitos para %s"
|
||||
|
||||
#: src/main/main.c:74
|
||||
#: src/main/main.c:230
|
||||
msgid "(input)"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/main.c:319
|
||||
msgid "state allocation failed"
|
||||
msgstr "alocação de memória de status falhou"
|
||||
|
||||
#: src/main/options.c:173
|
||||
msgid "option structure allocation failed"
|
||||
msgstr "erro na alocação da estrutura de opções"
|
||||
|
||||
#: src/main/options.c:192
|
||||
msgid "option structure argv allocation failed"
|
||||
msgstr "erro na alocação da estrutura de opções argv"
|
||||
|
||||
#: src/main/options.c:254
|
||||
msgid "integer argument expected"
|
||||
msgstr "argumento inteiro esperado"
|
||||
|
||||
#: src/main/options.c:265
|
||||
msgid "numeric argument expected"
|
||||
msgstr "argumento numérico esperado"
|
||||
|
||||
#: src/main/options.c:276
|
||||
msgid "process ID or pid:fd pair expected"
|
||||
msgstr "ID do processo ou par pid:fd esperado"
|
||||
|
||||
#: src/main/options.c:283
|
||||
msgid "invalid process ID"
|
||||
msgstr "ID de processo inválido"
|
||||
|
||||
#: src/main/options.c:384 src/pv/file.c:323
|
||||
#: src/main/options.c:144 src/pv/file.c:324
|
||||
msgid "failed to stat file"
|
||||
msgstr "erro obtendo informações do arquivo"
|
||||
|
||||
#: src/main/options.c:487
|
||||
#: src/main/options.c:158
|
||||
msgid "is a directory"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:187
|
||||
msgid "failed to generate sysfs filename"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:209
|
||||
msgid "failed to read sysfs size file"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:229
|
||||
msgid "failed to open block device"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:239
|
||||
msgid "failed to determine size of block device"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:344
|
||||
msgid "option structure allocation failed"
|
||||
msgstr "erro na alocação da estrutura de opções"
|
||||
|
||||
#: src/main/options.c:363
|
||||
msgid "option structure argv allocation failed"
|
||||
msgstr "erro na alocação da estrutura de opções argv"
|
||||
|
||||
#: src/main/options.c:425
|
||||
msgid "integer argument expected"
|
||||
msgstr "argumento inteiro esperado"
|
||||
|
||||
#: src/main/options.c:436
|
||||
msgid "numeric argument expected"
|
||||
msgstr "argumento numérico esperado"
|
||||
|
||||
#: src/main/options.c:447
|
||||
msgid "process ID or pid:fd pair expected"
|
||||
msgstr "ID do processo ou par pid:fd esperado"
|
||||
|
||||
#: src/main/options.c:454
|
||||
msgid "invalid process ID"
|
||||
msgstr "ID de processo inválido"
|
||||
|
||||
#: src/main/options.c:679
|
||||
#, c-format
|
||||
msgid "Try `%s --help' for more information."
|
||||
msgstr "Tente `%s --help' para maiores informações."
|
||||
|
||||
#: src/main/options.c:489
|
||||
#: src/main/options.c:681
|
||||
#, c-format
|
||||
msgid "Try `%s -h' for more information."
|
||||
msgstr "Tente `%s -h' para maiores informações."
|
||||
|
||||
#: src/main/options.c:520
|
||||
#: src/main/options.c:712
|
||||
msgid ""
|
||||
"cannot use line mode or transfer modifier options when watching file "
|
||||
"descriptors"
|
||||
@@ -290,29 +343,29 @@ msgstr ""
|
||||
"não pode usar o modo de linha ou opções de modificador de transferência ao "
|
||||
"assistir os descritores de arquivo"
|
||||
|
||||
#: src/main/options.c:529
|
||||
#: src/main/options.c:721
|
||||
msgid "cannot use cursor positioning when watching file descriptors"
|
||||
msgstr ""
|
||||
"não pode usar o posicionamento do cursor ao observar os descritores de "
|
||||
"arquivo"
|
||||
|
||||
#: src/main/options.c:538
|
||||
#: src/main/options.c:730
|
||||
msgid "cannot use remote control when watching file descriptors"
|
||||
msgstr "não pode usar o controle remoto ao assistir os descritores de arquivo"
|
||||
|
||||
#: src/main/options.c:547
|
||||
#: src/main/options.c:739
|
||||
msgid "cannot transfer files when watching file descriptors"
|
||||
msgstr "não pode transferir arquivos ao assistir descritores de arquivo"
|
||||
|
||||
#: src/main/options.c:562
|
||||
#: src/main/options.c:754
|
||||
msgid "not available on systems without /proc/self/fdinfo"
|
||||
msgstr "não disponível em sistemas sem /proc/self/fdinfo"
|
||||
|
||||
#: src/main/remote.c:295
|
||||
#: src/main/remote.c:304
|
||||
msgid "message not received"
|
||||
msgstr "mensagem não recebida"
|
||||
|
||||
#: src/main/remote.c:422
|
||||
#: src/main/remote.c:431
|
||||
msgid "SA_SIGINFO not supported on this system"
|
||||
msgstr "SA_SIGINFO não suportado neste sistema"
|
||||
|
||||
@@ -332,135 +385,157 @@ msgstr ""
|
||||
msgid "Project web site"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/cursor.c:87
|
||||
#: src/pv/cursor.c:61
|
||||
msgid "failed to get terminal name"
|
||||
msgstr "erro ao ler o nome do terminal"
|
||||
|
||||
#: src/pv/cursor.c:130
|
||||
#: src/pv/cursor.c:106
|
||||
msgid "failed to open lock file"
|
||||
msgstr "erro ao abrir arquivo de bloqueio"
|
||||
|
||||
#: src/pv/cursor.c:163
|
||||
#: src/pv/cursor.c:139
|
||||
msgid "lock attempt failed"
|
||||
msgstr "tentativa de bloqueio falhou"
|
||||
|
||||
#: src/pv/cursor.c:424
|
||||
#: src/pv/cursor.c:400
|
||||
msgid "failed to open terminal"
|
||||
msgstr "erro abrindo o terminal"
|
||||
|
||||
#: src/pv/display.c:192
|
||||
#: src/pv/display.c:233
|
||||
msgid "yzafpnum kMGTPEZY"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:210
|
||||
#: src/pv/display.c:251
|
||||
msgid "yzafpnum KMGTPEZY"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:746 src/pv/transfer.c:910
|
||||
#: src/pv/display.c:681 src/pv/transfer.c:1011
|
||||
msgid "buffer allocation failed"
|
||||
msgstr "erro alocando o buffer"
|
||||
|
||||
#: src/pv/display.c:845
|
||||
#: src/pv/display.c:810
|
||||
msgid "b"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:848 src/pv/transfer.c:595
|
||||
#: src/pv/display.c:813 src/pv/transfer.c:602
|
||||
msgid "B"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:890 src/pv/display.c:907
|
||||
#: src/pv/display.c:857 src/pv/display.c:872 src/pv/display.c:1091
|
||||
#: src/pv/loop.c:549
|
||||
msgid "b/s"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:895 src/pv/display.c:912
|
||||
#: src/pv/display.c:861 src/pv/display.c:876 src/pv/display.c:1095
|
||||
msgid "/s"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:895 src/pv/display.c:912
|
||||
#: src/pv/display.c:861 src/pv/display.c:876 src/pv/display.c:1095
|
||||
#: src/pv/loop.c:549
|
||||
msgid "B/s"
|
||||
msgstr "B/s"
|
||||
|
||||
#: src/pv/display.c:940 src/pv/display.c:944 src/pv/display.c:1010
|
||||
#: src/pv/display.c:904 src/pv/display.c:908
|
||||
msgid "ETA"
|
||||
msgstr "ETA"
|
||||
|
||||
#: src/pv/file.c:148
|
||||
#: src/pv/display.c:974
|
||||
msgid "FIN"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/file.c:149
|
||||
msgid "failed to seek to start of output"
|
||||
msgstr "não pode mover para o início da produção"
|
||||
|
||||
#: src/pv/file.c:293
|
||||
#: src/pv/file.c:294
|
||||
msgid "failed to close file"
|
||||
msgstr "erro fechando o arquivo"
|
||||
|
||||
#: src/pv/file.c:316
|
||||
#: src/pv/file.c:317
|
||||
msgid "failed to read file"
|
||||
msgstr "erro lendo o arquivo"
|
||||
|
||||
#: src/pv/file.c:331
|
||||
#: src/pv/file.c:332
|
||||
msgid "failed to stat output file"
|
||||
msgstr "erro obtendo informações do arquivo de saída"
|
||||
|
||||
#: src/pv/file.c:353
|
||||
#: src/pv/file.c:354
|
||||
msgid "input file is output file"
|
||||
msgstr "os arquivos de entrada e saída são o mesmo"
|
||||
|
||||
#: src/pv/file.c:411
|
||||
#: src/pv/file.c:412
|
||||
msgid "(none)"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/file.c:413
|
||||
#: src/pv/file.c:414
|
||||
msgid "(stdin)"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/loop.c:570 src/pv/loop.c:621 src/pv/loop.c:662 src/pv/watchpid.c:99
|
||||
#: src/pv/loop.c:548
|
||||
msgid "rate min/avg/max/mdev"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/loop.c:560
|
||||
msgid "rate not measured"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/loop.c:767 src/pv/loop.c:818 src/pv/loop.c:859 src/pv/watchpid.c:99
|
||||
#: src/pv/watchpid.c:109 src/pv/watchpid.c:120 src/pv/watchpid.c:128
|
||||
#: src/pv/watchpid.c:165 src/pv/watchpid.c:184 src/pv/watchpid.c:192
|
||||
#: src/pv/watchpid.c:202 src/pv/watchpid.c:293 src/pv/watchpid.c:301
|
||||
#: src/pv/watchpid.c:377 src/pv/watchpid.c:398
|
||||
#: src/pv/watchpid.c:202 src/pv/watchpid.c:300 src/pv/watchpid.c:308
|
||||
#: src/pv/watchpid.c:384 src/pv/watchpid.c:405
|
||||
msgid "pid"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/state.c:36
|
||||
#: src/pv/state.c:40
|
||||
msgid "history structure allocation failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/state.c:386 src/pv/state.c:397
|
||||
#: src/pv/state.c:572 src/pv/state.c:583
|
||||
msgid "file list allocation failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:457
|
||||
#: src/pv/transfer.c:464
|
||||
msgid "read failed"
|
||||
msgstr "erro de leitura"
|
||||
|
||||
#: src/pv/transfer.c:480
|
||||
#: src/pv/transfer.c:487
|
||||
msgid "warning: read errors detected"
|
||||
msgstr "aviso: erros de leitura detectados"
|
||||
|
||||
#: src/pv/transfer.c:496
|
||||
#: src/pv/transfer.c:503
|
||||
msgid "file is not seekable"
|
||||
msgstr "não pode mover dentro do arquivo"
|
||||
|
||||
#: src/pv/transfer.c:574
|
||||
#: src/pv/transfer.c:581
|
||||
msgid "failed to seek past error"
|
||||
msgstr "não pode ir além do erro"
|
||||
|
||||
#: src/pv/transfer.c:594
|
||||
#: src/pv/transfer.c:601
|
||||
msgid "skipped past read error"
|
||||
msgstr "ignorado erro de leitura"
|
||||
|
||||
#: src/pv/transfer.c:634
|
||||
#: src/pv/transfer.c:642
|
||||
msgid "no transfer buffer allocated"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:647
|
||||
msgid "failed to set alarm signal handler"
|
||||
#: src/pv/transfer.c:684
|
||||
msgid "failed to set interval timer"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:774
|
||||
#: src/pv/transfer.c:710
|
||||
msgid "failed to clear interval timer"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:740
|
||||
msgid "line position buffer allocation failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:872
|
||||
msgid "write failed"
|
||||
msgstr "erro de gravação"
|
||||
|
||||
#: src/pv/transfer.c:1007
|
||||
#: src/pv/transfer.c:1109
|
||||
msgid "select call failed"
|
||||
msgstr "erro na chamada da função select"
|
||||
|
||||
|
||||
@@ -0,0 +1,544 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Report-Msgid-Bugs-To: pv@ivarch.com\n"
|
||||
"POT-Creation-Date: 2024-12-02 17:56+0000\n"
|
||||
"PO-Revision-Date: 2024-10-22 18:07+0000\n"
|
||||
"Last-Translator: 0ko <0ko@users.noreply.translate.codeberg.org>\n"
|
||||
"Language-Team: Russian <https://translate.codeberg.org/projects/pv/pv/ru/>\n"
|
||||
"Language: ru\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
|
||||
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
|
||||
"X-Generator: Weblate 5.8.1\n"
|
||||
|
||||
#: src/main/help.c:284
|
||||
msgid "show progress bar"
|
||||
msgstr "показать полосу прогресса"
|
||||
|
||||
#: src/main/help.c:287
|
||||
msgid "show elapsed time"
|
||||
msgstr "показать прошедшее время"
|
||||
|
||||
#: src/main/help.c:290
|
||||
msgid "show estimated time of arrival (completion)"
|
||||
msgstr "показать примерное время завершения"
|
||||
|
||||
#: src/main/help.c:293
|
||||
msgid "show absolute estimated time of arrival (completion)"
|
||||
msgstr "показать примерное абсолютное время завершения"
|
||||
|
||||
#: src/main/help.c:296
|
||||
msgid "show data transfer rate counter"
|
||||
msgstr "показать скорость передачи данных"
|
||||
|
||||
#: src/main/help.c:299
|
||||
msgid "show data transfer average rate counter"
|
||||
msgstr "показать среднюю скорость передачи данных"
|
||||
|
||||
#: src/main/help.c:302
|
||||
msgid "show number of bytes transferred"
|
||||
msgstr "показать объём переданных данных в байтах"
|
||||
|
||||
#: src/main/help.c:305
|
||||
msgid "show percentage of transfer buffer in use"
|
||||
msgstr "показать использование буфера передачи в процентах"
|
||||
|
||||
#: src/main/help.c:307
|
||||
msgid "NUM"
|
||||
msgstr "КОЛ"
|
||||
|
||||
#: src/main/help.c:308
|
||||
msgid "show NUM bytes last written"
|
||||
msgstr "показать КОЛ байт, переданных в последний раз"
|
||||
|
||||
#: src/main/help.c:310
|
||||
msgid "FORMAT"
|
||||
msgstr "ФОРМАТ"
|
||||
|
||||
#: src/main/help.c:311
|
||||
msgid "set output format to FORMAT"
|
||||
msgstr "указать формат вывода как ФОРМАТ"
|
||||
|
||||
#: src/main/help.c:314
|
||||
msgid "output percentages, not visual information"
|
||||
msgstr "показать проценты вместо визуальной информации"
|
||||
|
||||
#: src/main/help.c:317
|
||||
msgid "do not output any transfer information at all"
|
||||
msgstr "не отображать никакую информацию о передаче"
|
||||
|
||||
#: src/main/help.c:321
|
||||
msgid "show number of bits transferred"
|
||||
msgstr "показать объём переданных данных в битах"
|
||||
|
||||
#: src/main/help.c:324
|
||||
msgid "treat suffixes as multiples of 1000 rather than 1024"
|
||||
msgstr "считать суффиксы как умножители на 1000, а не на 1024"
|
||||
|
||||
#: src/main/help.c:327
|
||||
msgid "display nothing until first byte transferred"
|
||||
msgstr "ничего не показывать, пока не будет передан первый байт"
|
||||
|
||||
#: src/main/help.c:329 src/main/help.c:344 src/main/help.c:347
|
||||
msgid "SEC"
|
||||
msgstr "СЕК"
|
||||
|
||||
#: src/main/help.c:330
|
||||
msgid "display nothing until SEC seconds have passed"
|
||||
msgstr "ничего не показывать, пока не пройдёт СЕК секунд"
|
||||
|
||||
#: src/main/help.c:332
|
||||
msgid "SIZE"
|
||||
msgstr "РАЗМ"
|
||||
|
||||
#: src/main/help.c:333
|
||||
msgid "set estimated data size to SIZE bytes"
|
||||
msgstr "указать ожидаемый объём данных как РАЗМ байт"
|
||||
|
||||
#: src/main/help.c:336
|
||||
msgid "if size unknown, show rate vs max rate"
|
||||
msgstr "если объём неизвестен, показать скорость и макс. скорость"
|
||||
|
||||
#: src/main/help.c:339
|
||||
msgid "count lines instead of bytes"
|
||||
msgstr "считать линии вместо байт"
|
||||
|
||||
#: src/main/help.c:342
|
||||
msgid "lines are null-terminated"
|
||||
msgstr "строки прерываются нулями"
|
||||
|
||||
#: src/main/help.c:345
|
||||
msgid "update every SEC seconds"
|
||||
msgstr "обновлять каждые СЕК секунд"
|
||||
|
||||
#: src/main/help.c:348
|
||||
msgid "compute average rate over past SEC seconds (default 30s)"
|
||||
msgstr "вычислять среднюю скорость за последние СЕК секунд (по умолчанию 30)"
|
||||
|
||||
#: src/main/help.c:350
|
||||
msgid "WIDTH"
|
||||
msgstr "ШИРИНА"
|
||||
|
||||
#: src/main/help.c:351
|
||||
msgid "assume terminal is WIDTH characters wide"
|
||||
msgstr "считать, что в одной строке помещается ШИРИНА символов"
|
||||
|
||||
#: src/main/help.c:353
|
||||
msgid "HEIGHT"
|
||||
msgstr "ВЫСОТА"
|
||||
|
||||
#: src/main/help.c:354
|
||||
msgid "assume terminal is HEIGHT rows high"
|
||||
msgstr "считать, что на экране помещается ВЫСОТА строк"
|
||||
|
||||
#: src/main/help.c:356
|
||||
msgid "NAME"
|
||||
msgstr "ИМЯ"
|
||||
|
||||
#: src/main/help.c:357
|
||||
msgid "prefix visual information with NAME"
|
||||
msgstr "писать ИМЯ до визуальной информации"
|
||||
|
||||
#: src/main/help.c:359
|
||||
msgid "SPEC"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:360
|
||||
msgid "also send progress to SPEC"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:363
|
||||
msgid "output transfer statistics at the end"
|
||||
msgstr "после завершения показать статистику"
|
||||
|
||||
#: src/main/help.c:366
|
||||
msgid "output even if standard error is not a terminal"
|
||||
msgstr "вевести, даже если стд. ошибка не является терминалом"
|
||||
|
||||
#: src/main/help.c:369
|
||||
msgid "use cursor positioning escape sequences"
|
||||
msgstr ""
|
||||
"использовать символьные последовательности для позиционирования курсора"
|
||||
|
||||
#: src/main/help.c:372 src/main/help.c:402 src/main/help.c:414
|
||||
#: src/main/help.c:424
|
||||
msgid "FILE"
|
||||
msgstr "ФАЙЛ"
|
||||
|
||||
#: src/main/help.c:373
|
||||
msgid "write output to FILE instead of stdout"
|
||||
msgstr "направить вывод в ФАЙЛ вместо стд. вывода"
|
||||
|
||||
#: src/main/help.c:375
|
||||
msgid "RATE"
|
||||
msgstr "СКОР"
|
||||
|
||||
#: src/main/help.c:376
|
||||
msgid "limit transfer to RATE bytes per second"
|
||||
msgstr "ограничить скорость передачи до СКОР байт/сек"
|
||||
|
||||
#: src/main/help.c:378 src/main/help.c:387
|
||||
msgid "BYTES"
|
||||
msgstr "БАЙТ"
|
||||
|
||||
#: src/main/help.c:379
|
||||
msgid "use a buffer size of BYTES"
|
||||
msgstr "использовать буфер размера БАЙТ"
|
||||
|
||||
#: src/main/help.c:382
|
||||
msgid "never use splice(), always use read/write"
|
||||
msgstr "использовать чтение/запись вместо splice()"
|
||||
|
||||
#: src/main/help.c:385
|
||||
msgid "skip read errors in input"
|
||||
msgstr "пропустить ошибки чтения во вводе"
|
||||
|
||||
#: src/main/help.c:388
|
||||
msgid "skip errors in BYTES blocks at a time"
|
||||
msgstr "пропускать ошибки в <БАЙТ> блоках за раз"
|
||||
|
||||
#: src/main/help.c:391
|
||||
msgid "stop after --size bytes have been transferred"
|
||||
msgstr "остановить после передачи --size байт"
|
||||
|
||||
#: src/main/help.c:394
|
||||
msgid "flush cache to disk after every write"
|
||||
msgstr "сбрасывать кеш на диск каждый раз"
|
||||
|
||||
#: src/main/help.c:397
|
||||
msgid "use direct I/O to bypass cache"
|
||||
msgstr "использовать прямой ввод/вывод для обхода кеша"
|
||||
|
||||
#: src/main/help.c:400
|
||||
msgid "discard input instead of writing to output"
|
||||
msgstr "отбрасывать ввод вместо записи в вывод"
|
||||
|
||||
#: src/main/help.c:403
|
||||
msgid "write all input to FILE before writing to output"
|
||||
msgstr "записывать весь ввод в ФАЙЛ прежде, чем отправлять на вывод"
|
||||
|
||||
#: src/main/help.c:405
|
||||
msgid "PID[:FD]"
|
||||
msgstr "ИДпр[:FD]"
|
||||
|
||||
#: src/main/help.c:406
|
||||
msgid "watch file FD opened by process PID"
|
||||
msgstr "следить за FD файла, открытого процессом ИДпр"
|
||||
|
||||
#: src/main/help.c:409
|
||||
msgid "PID"
|
||||
msgstr "ИДпр"
|
||||
|
||||
#: src/main/help.c:410
|
||||
msgid "update settings of process PID"
|
||||
msgstr "обновить настройки ИДпр процесса"
|
||||
|
||||
#: src/main/help.c:415
|
||||
msgid "save process ID in FILE"
|
||||
msgstr "сохранить ИД процесса в ФАЙЛ"
|
||||
|
||||
#: src/main/help.c:418
|
||||
msgid "show this help and exit"
|
||||
msgstr "показать справку и завершить работу"
|
||||
|
||||
#: src/main/help.c:421
|
||||
msgid "show version information and exit"
|
||||
msgstr "показать версию программы и завершить работу"
|
||||
|
||||
#: src/main/help.c:425
|
||||
msgid "write debug logs to FILE"
|
||||
msgstr "вести запись отладочного журнала в ФАЙЛ"
|
||||
|
||||
#: src/main/help.c:450
|
||||
#, c-format
|
||||
msgid "Usage: %s [OPTION] [FILE]..."
|
||||
msgstr "Использование: %s [ОПЦИИ] [ФАЙЛ]..."
|
||||
|
||||
#: src/main/help.c:461
|
||||
msgid ""
|
||||
"Concatenate FILE(s), or standard input, to standard output, with monitoring."
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:598
|
||||
#, c-format
|
||||
msgid "Please report any bugs to: %s"
|
||||
msgstr "Сообщайте о проблемах на: %s"
|
||||
|
||||
#: src/main/main.c:230
|
||||
msgid "(input)"
|
||||
msgstr "(ввод)"
|
||||
|
||||
#: src/main/main.c:319
|
||||
msgid "state allocation failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:144 src/pv/file.c:324
|
||||
msgid "failed to stat file"
|
||||
msgstr "не удалось получить информацию о файле"
|
||||
|
||||
#: src/main/options.c:158
|
||||
msgid "is a directory"
|
||||
msgstr "является каталогом"
|
||||
|
||||
#: src/main/options.c:187
|
||||
msgid "failed to generate sysfs filename"
|
||||
msgstr "не удалось создать имя файла sysfs"
|
||||
|
||||
#: src/main/options.c:209
|
||||
msgid "failed to read sysfs size file"
|
||||
msgstr "не удалось узнать размер файла sysfs"
|
||||
|
||||
#: src/main/options.c:229
|
||||
msgid "failed to open block device"
|
||||
msgstr "не удалось открыть блочное устройство"
|
||||
|
||||
#: src/main/options.c:239
|
||||
msgid "failed to determine size of block device"
|
||||
msgstr "не удалось определить размер блочного устройства"
|
||||
|
||||
#: src/main/options.c:344
|
||||
msgid "option structure allocation failed"
|
||||
msgstr "не удалось выделить память для структуры опций"
|
||||
|
||||
#: src/main/options.c:363
|
||||
msgid "option structure argv allocation failed"
|
||||
msgstr "не удалось выделить память для структуры опций argv"
|
||||
|
||||
#: src/main/options.c:425
|
||||
msgid "integer argument expected"
|
||||
msgstr "ожидалось целое число"
|
||||
|
||||
#: src/main/options.c:436
|
||||
msgid "numeric argument expected"
|
||||
msgstr "ожидалось число"
|
||||
|
||||
#: src/main/options.c:447
|
||||
msgid "process ID or pid:fd pair expected"
|
||||
msgstr "ожидался ИД процесса или пара ИДпр:ДФ"
|
||||
|
||||
#: src/main/options.c:454
|
||||
msgid "invalid process ID"
|
||||
msgstr "неправильный ИД процесса"
|
||||
|
||||
#: src/main/options.c:679
|
||||
#, c-format
|
||||
msgid "Try `%s --help' for more information."
|
||||
msgstr "Выполните `%s --help' для получения подробностей."
|
||||
|
||||
#: src/main/options.c:681
|
||||
#, c-format
|
||||
msgid "Try `%s -h' for more information."
|
||||
msgstr "Выполните `%s -h' для получения подробностей."
|
||||
|
||||
#: src/main/options.c:712
|
||||
msgid ""
|
||||
"cannot use line mode or transfer modifier options when watching file "
|
||||
"descriptors"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:721
|
||||
msgid "cannot use cursor positioning when watching file descriptors"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:730
|
||||
msgid "cannot use remote control when watching file descriptors"
|
||||
msgstr "удалённое управление невозможно при отслеживании дескрипторов файлов"
|
||||
|
||||
#: src/main/options.c:739
|
||||
msgid "cannot transfer files when watching file descriptors"
|
||||
msgstr "передача файлов невозможна при отслеживании дескрипторов файлов"
|
||||
|
||||
#: src/main/options.c:754
|
||||
msgid "not available on systems without /proc/self/fdinfo"
|
||||
msgstr "невозможно на системах без /proc/self/fdinfo"
|
||||
|
||||
#: src/main/remote.c:304
|
||||
msgid "message not received"
|
||||
msgstr "сообщение не получено"
|
||||
|
||||
#: src/main/remote.c:431
|
||||
msgid "SA_SIGINFO not supported on this system"
|
||||
msgstr "Этой системой не поддерживается SA_SIGINFO"
|
||||
|
||||
#: src/main/version.c:28
|
||||
msgid "License: GPLv3+ <https://www.gnu.org/licenses/gpl-3.0.html>"
|
||||
msgstr "Лицензия: GPLv3+ <https://www.gnu.org/licenses/gpl-3.0.html>"
|
||||
|
||||
#: src/main/version.c:29
|
||||
msgid "This is free software: you are free to change and redistribute it."
|
||||
msgstr "Это свободная программа. Вы можете изменять и распространять её."
|
||||
|
||||
#: src/main/version.c:30
|
||||
msgid "There is NO WARRANTY, to the extent permitted by law."
|
||||
msgstr ""
|
||||
"Разработчики не дают никаких гарантий, связанных с работой этой программы, "
|
||||
"насколько это юридически возможно."
|
||||
|
||||
#: src/main/version.c:32
|
||||
msgid "Project web site"
|
||||
msgstr "Веб-сайт проекта"
|
||||
|
||||
#: src/pv/cursor.c:61
|
||||
msgid "failed to get terminal name"
|
||||
msgstr "не удалось получить имя терминала"
|
||||
|
||||
#: src/pv/cursor.c:106
|
||||
msgid "failed to open lock file"
|
||||
msgstr "не удалось открыть блокирующий файл"
|
||||
|
||||
#: src/pv/cursor.c:139
|
||||
msgid "lock attempt failed"
|
||||
msgstr "попытка блокировки не удалась"
|
||||
|
||||
#: src/pv/cursor.c:400
|
||||
msgid "failed to open terminal"
|
||||
msgstr "не удалось открыть терминал"
|
||||
|
||||
#: src/pv/display.c:233
|
||||
msgid "yzafpnum kMGTPEZY"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:251
|
||||
msgid "yzafpnum KMGTPEZY"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:681 src/pv/transfer.c:1011
|
||||
msgid "buffer allocation failed"
|
||||
msgstr "не удалось выделить память для буфера"
|
||||
|
||||
#: src/pv/display.c:810
|
||||
msgid "b"
|
||||
msgstr "бит"
|
||||
|
||||
#: src/pv/display.c:813 src/pv/transfer.c:602
|
||||
msgid "B"
|
||||
msgstr "байт"
|
||||
|
||||
#: src/pv/display.c:857 src/pv/display.c:872 src/pv/display.c:1091
|
||||
#: src/pv/loop.c:549
|
||||
msgid "b/s"
|
||||
msgstr "бит/с"
|
||||
|
||||
#: src/pv/display.c:861 src/pv/display.c:876 src/pv/display.c:1095
|
||||
msgid "/s"
|
||||
msgstr "/с"
|
||||
|
||||
#: src/pv/display.c:861 src/pv/display.c:876 src/pv/display.c:1095
|
||||
#: src/pv/loop.c:549
|
||||
msgid "B/s"
|
||||
msgstr "байт/с"
|
||||
|
||||
#: src/pv/display.c:904 src/pv/display.c:908
|
||||
msgid "ETA"
|
||||
msgstr "ОЖИД"
|
||||
|
||||
#: src/pv/display.c:974
|
||||
msgid "FIN"
|
||||
msgstr "ЗАВЕРШ"
|
||||
|
||||
#: src/pv/file.c:149
|
||||
msgid "failed to seek to start of output"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/file.c:294
|
||||
msgid "failed to close file"
|
||||
msgstr "не удалось закрыть файл"
|
||||
|
||||
#: src/pv/file.c:317
|
||||
msgid "failed to read file"
|
||||
msgstr "не удалось прочесть файл"
|
||||
|
||||
#: src/pv/file.c:332
|
||||
msgid "failed to stat output file"
|
||||
msgstr "не удалось получить информацию о выходном файле"
|
||||
|
||||
#: src/pv/file.c:354
|
||||
msgid "input file is output file"
|
||||
msgstr "пути исходного и выходного файлов одинаковы"
|
||||
|
||||
#: src/pv/file.c:412
|
||||
msgid "(none)"
|
||||
msgstr "(нет)"
|
||||
|
||||
#: src/pv/file.c:414
|
||||
msgid "(stdin)"
|
||||
msgstr "(стд. ввод)"
|
||||
|
||||
#: src/pv/loop.c:548
|
||||
msgid "rate min/avg/max/mdev"
|
||||
msgstr "скор. мин/сред/макс/дев"
|
||||
|
||||
#: src/pv/loop.c:560
|
||||
msgid "rate not measured"
|
||||
msgstr "скорость не изменяется"
|
||||
|
||||
#: src/pv/loop.c:767 src/pv/loop.c:818 src/pv/loop.c:859 src/pv/watchpid.c:99
|
||||
#: src/pv/watchpid.c:109 src/pv/watchpid.c:120 src/pv/watchpid.c:128
|
||||
#: src/pv/watchpid.c:165 src/pv/watchpid.c:184 src/pv/watchpid.c:192
|
||||
#: src/pv/watchpid.c:202 src/pv/watchpid.c:300 src/pv/watchpid.c:308
|
||||
#: src/pv/watchpid.c:384 src/pv/watchpid.c:405
|
||||
msgid "pid"
|
||||
msgstr "ИДпр"
|
||||
|
||||
#: src/pv/state.c:40
|
||||
msgid "history structure allocation failed"
|
||||
msgstr "не удалось выделить память для структуры истории"
|
||||
|
||||
#: src/pv/state.c:572 src/pv/state.c:583
|
||||
msgid "file list allocation failed"
|
||||
msgstr "не удалось выделить память для списка файлов"
|
||||
|
||||
#: src/pv/transfer.c:464
|
||||
msgid "read failed"
|
||||
msgstr "чтение не удалось"
|
||||
|
||||
#: src/pv/transfer.c:487
|
||||
msgid "warning: read errors detected"
|
||||
msgstr "внимание: замечены ошибки чтения"
|
||||
|
||||
#: src/pv/transfer.c:503
|
||||
msgid "file is not seekable"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:581
|
||||
msgid "failed to seek past error"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:601
|
||||
msgid "skipped past read error"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:642
|
||||
msgid "no transfer buffer allocated"
|
||||
msgstr "не выделена память для буфера передачи"
|
||||
|
||||
#: src/pv/transfer.c:684
|
||||
msgid "failed to set interval timer"
|
||||
msgstr "не удалось задать измеритель временного промежутка"
|
||||
|
||||
#: src/pv/transfer.c:710
|
||||
msgid "failed to clear interval timer"
|
||||
msgstr "не удалось очистить измеритель временного промежутка"
|
||||
|
||||
#: src/pv/transfer.c:740
|
||||
msgid "line position buffer allocation failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:872
|
||||
msgid "write failed"
|
||||
msgstr "запись не удалась"
|
||||
|
||||
#: src/pv/transfer.c:1109
|
||||
msgid "select call failed"
|
||||
msgstr "запрос выборки не удался"
|
||||
|
||||
#: src/pv/watchpid.c:109 src/pv/watchpid.c:121 src/pv/watchpid.c:130
|
||||
#: src/pv/watchpid.c:184 src/pv/watchpid.c:193 src/pv/watchpid.c:204
|
||||
msgid "fd"
|
||||
msgstr "дф"
|
||||
|
||||
#: src/pv/watchpid.c:130 src/pv/watchpid.c:204
|
||||
msgid "not a regular file or block device"
|
||||
msgstr "не является обычным файлом или блочным устройством"
|
||||
@@ -0,0 +1,545 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: pv 1.8.14\n"
|
||||
"Report-Msgid-Bugs-To: pv@ivarch.com\n"
|
||||
"POT-Creation-Date: 2024-12-02 17:56+0000\n"
|
||||
"PO-Revision-Date: 2024-10-12 23:51+0000\n"
|
||||
"Last-Translator: a-j-wood <a-j-wood@users.noreply.translate.codeberg.org>\n"
|
||||
"Language-Team: Turkish <https://translate.codeberg.org/projects/pv/pv/tr/>\n"
|
||||
"Language: tr\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 5.7.2\n"
|
||||
|
||||
#: src/main/help.c:284
|
||||
msgid "show progress bar"
|
||||
msgstr "ilerleme çubuğunu göster"
|
||||
|
||||
#: src/main/help.c:287
|
||||
msgid "show elapsed time"
|
||||
msgstr "geçen süreyi göster"
|
||||
|
||||
#: src/main/help.c:290
|
||||
msgid "show estimated time of arrival (completion)"
|
||||
msgstr "tahmini varış (tamamlanma) zamanını göster"
|
||||
|
||||
#: src/main/help.c:293
|
||||
msgid "show absolute estimated time of arrival (completion)"
|
||||
msgstr "mutlak tahmini varış (tamamlanma) zamanını göster"
|
||||
|
||||
#: src/main/help.c:296
|
||||
msgid "show data transfer rate counter"
|
||||
msgstr "veri aktarım oranı sayacını göster"
|
||||
|
||||
#: src/main/help.c:299
|
||||
msgid "show data transfer average rate counter"
|
||||
msgstr "veri aktarımı ortalama hız sayacını göster"
|
||||
|
||||
#: src/main/help.c:302
|
||||
msgid "show number of bytes transferred"
|
||||
msgstr "aktarılan bayt sayısını göster"
|
||||
|
||||
#: src/main/help.c:305
|
||||
msgid "show percentage of transfer buffer in use"
|
||||
msgstr "aktarım tamponunun kullanım yüzdesini göster"
|
||||
|
||||
#: src/main/help.c:307
|
||||
msgid "NUM"
|
||||
msgstr "NUM"
|
||||
|
||||
#: src/main/help.c:308
|
||||
msgid "show NUM bytes last written"
|
||||
msgstr "son yazılan NUM baytlarını göster"
|
||||
|
||||
#: src/main/help.c:310
|
||||
msgid "FORMAT"
|
||||
msgstr "FORMAT"
|
||||
|
||||
#: src/main/help.c:311
|
||||
msgid "set output format to FORMAT"
|
||||
msgstr "çıktı formatını FORMAT olarak ayarlayın"
|
||||
|
||||
#: src/main/help.c:314
|
||||
msgid "output percentages, not visual information"
|
||||
msgstr "görsel bilgileri değil, yüzdeleri çıktı olarak yazdır"
|
||||
|
||||
#: src/main/help.c:317
|
||||
msgid "do not output any transfer information at all"
|
||||
msgstr "hiçbir transfer bilgisini yazdırma"
|
||||
|
||||
#: src/main/help.c:321
|
||||
msgid "show number of bits transferred"
|
||||
msgstr "aktarılan bit sayısını göster"
|
||||
|
||||
#: src/main/help.c:324
|
||||
msgid "treat suffixes as multiples of 1000 rather than 1024"
|
||||
msgstr "ekleri 1024 yerine 1000'in katları olarak değerlendir"
|
||||
|
||||
#: src/main/help.c:327
|
||||
msgid "display nothing until first byte transferred"
|
||||
msgstr "ilk bayt aktarılana kadar hiçbir şey gösterme"
|
||||
|
||||
#: src/main/help.c:329 src/main/help.c:344 src/main/help.c:347
|
||||
msgid "SEC"
|
||||
msgstr "SEC"
|
||||
|
||||
#: src/main/help.c:330
|
||||
msgid "display nothing until SEC seconds have passed"
|
||||
msgstr "SEC saniye geçene kadar hiçbir şey gösterme"
|
||||
|
||||
#: src/main/help.c:332
|
||||
msgid "SIZE"
|
||||
msgstr "BOYUT"
|
||||
|
||||
#: src/main/help.c:333
|
||||
msgid "set estimated data size to SIZE bytes"
|
||||
msgstr "tahmini veri boyutunu BOYUT bayt olarak ayarlayın"
|
||||
|
||||
#: src/main/help.c:336
|
||||
msgid "if size unknown, show rate vs max rate"
|
||||
msgstr "boyut bilinmiyorsa, oranı maksimum oranla göster"
|
||||
|
||||
#: src/main/help.c:339
|
||||
msgid "count lines instead of bytes"
|
||||
msgstr "bayt yerine satır say"
|
||||
|
||||
#: src/main/help.c:342
|
||||
msgid "lines are null-terminated"
|
||||
msgstr "satırlar boş sonlandırılır"
|
||||
|
||||
#: src/main/help.c:345
|
||||
msgid "update every SEC seconds"
|
||||
msgstr "her SEC saniyede bir güncelleme"
|
||||
|
||||
#: src/main/help.c:348
|
||||
msgid "compute average rate over past SEC seconds (default 30s)"
|
||||
msgstr "geçmiş SEC saniyeleri üzerinden ortalama hızı hesapla (varsayılan 30s)"
|
||||
|
||||
#: src/main/help.c:350
|
||||
msgid "WIDTH"
|
||||
msgstr "GENİŞLİK"
|
||||
|
||||
#: src/main/help.c:351
|
||||
msgid "assume terminal is WIDTH characters wide"
|
||||
msgstr "terminalin GENİŞLİK karakter genişliğinde olduğunu varsayalım"
|
||||
|
||||
#: src/main/help.c:353
|
||||
msgid "HEIGHT"
|
||||
msgstr "YÜKSEKLİK"
|
||||
|
||||
#: src/main/help.c:354
|
||||
msgid "assume terminal is HEIGHT rows high"
|
||||
msgstr "terminalin YÜKSEKLİK sıraları yüksekliğinde olduğunu varsayalım"
|
||||
|
||||
#: src/main/help.c:356
|
||||
msgid "NAME"
|
||||
msgstr "İSİM"
|
||||
|
||||
#: src/main/help.c:357
|
||||
msgid "prefix visual information with NAME"
|
||||
msgstr "görsel bilgiyi İSİM ile öne ekle"
|
||||
|
||||
#: src/main/help.c:359
|
||||
msgid "SPEC"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:360
|
||||
msgid "also send progress to SPEC"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:363
|
||||
msgid "output transfer statistics at the end"
|
||||
msgstr "transfer istatistiklerini sonda göster"
|
||||
|
||||
#: src/main/help.c:366
|
||||
msgid "output even if standard error is not a terminal"
|
||||
msgstr "standart hata bir terminal olmasa bile çıktı yazdır"
|
||||
|
||||
#: src/main/help.c:369
|
||||
msgid "use cursor positioning escape sequences"
|
||||
msgstr "imleç konumlandırma kaçış dizilerini kullan"
|
||||
|
||||
#: src/main/help.c:372 src/main/help.c:402 src/main/help.c:414
|
||||
#: src/main/help.c:424
|
||||
msgid "FILE"
|
||||
msgstr "DOSYA"
|
||||
|
||||
#: src/main/help.c:373
|
||||
msgid "write output to FILE instead of stdout"
|
||||
msgstr "çıktıyı stdout yerine DOSYA'ya yaz"
|
||||
|
||||
#: src/main/help.c:375
|
||||
msgid "RATE"
|
||||
msgstr "ORAN"
|
||||
|
||||
#: src/main/help.c:376
|
||||
msgid "limit transfer to RATE bytes per second"
|
||||
msgstr "aktarımı saniye başına ORAN bayt ile sınırlandırın"
|
||||
|
||||
#: src/main/help.c:378 src/main/help.c:387
|
||||
msgid "BYTES"
|
||||
msgstr "BAYTLAR"
|
||||
|
||||
#: src/main/help.c:379
|
||||
msgid "use a buffer size of BYTES"
|
||||
msgstr "BAYTLAR tampon boyutu kullanın"
|
||||
|
||||
#: src/main/help.c:382
|
||||
msgid "never use splice(), always use read/write"
|
||||
msgstr "splice() kullanma, her zaman read/write kullan"
|
||||
|
||||
#: src/main/help.c:385
|
||||
msgid "skip read errors in input"
|
||||
msgstr "girdideki okuma hatalarını atla"
|
||||
|
||||
#: src/main/help.c:388
|
||||
msgid "skip errors in BYTES blocks at a time"
|
||||
msgstr "BAYTLAR blokları halinde hataları atla"
|
||||
|
||||
#: src/main/help.c:391
|
||||
msgid "stop after --size bytes have been transferred"
|
||||
msgstr "--size bayt transfer edildikten sonra dur"
|
||||
|
||||
#: src/main/help.c:394
|
||||
msgid "flush cache to disk after every write"
|
||||
msgstr "her yazmadan sonra önbelleği diske boşalt"
|
||||
|
||||
#: src/main/help.c:397
|
||||
msgid "use direct I/O to bypass cache"
|
||||
msgstr "Önbelleği atlamak için doğrudan I/O kullan"
|
||||
|
||||
#: src/main/help.c:400
|
||||
msgid "discard input instead of writing to output"
|
||||
msgstr "Girdiyi çıktıya yazmak yerine yok say"
|
||||
|
||||
#: src/main/help.c:403
|
||||
msgid "write all input to FILE before writing to output"
|
||||
msgstr "çıktıya yazmadan önce tüm girdiyi DOSYA'ya yaz"
|
||||
|
||||
#: src/main/help.c:405
|
||||
msgid "PID[:FD]"
|
||||
msgstr "PID[:FD]"
|
||||
|
||||
#: src/main/help.c:406
|
||||
msgid "watch file FD opened by process PID"
|
||||
msgstr "FD izleme dosyası PID işlemi tarafından açıldı"
|
||||
|
||||
#: src/main/help.c:409
|
||||
msgid "PID"
|
||||
msgstr "PID"
|
||||
|
||||
#: src/main/help.c:410
|
||||
msgid "update settings of process PID"
|
||||
msgstr "süreç PID ayarlarını güncelle"
|
||||
|
||||
#: src/main/help.c:415
|
||||
msgid "save process ID in FILE"
|
||||
msgstr "FILE'da işlem kimliğini (ID) kaydet"
|
||||
|
||||
#: src/main/help.c:418
|
||||
msgid "show this help and exit"
|
||||
msgstr "bu yardımı göster ve çık"
|
||||
|
||||
#: src/main/help.c:421
|
||||
msgid "show version information and exit"
|
||||
msgstr "sürüm bilgilerini göster ve çık"
|
||||
|
||||
#: src/main/help.c:425
|
||||
msgid "write debug logs to FILE"
|
||||
msgstr "Hata ayıklama kayıtlarını DOSYA'ya yaz"
|
||||
|
||||
#: src/main/help.c:450
|
||||
#, c-format
|
||||
msgid "Usage: %s [OPTION] [FILE]..."
|
||||
msgstr "Kullanım şekli: %s [AYAR] [DOSYA]..."
|
||||
|
||||
#: src/main/help.c:461
|
||||
msgid ""
|
||||
"Concatenate FILE(s), or standard input, to standard output, with monitoring."
|
||||
msgstr ""
|
||||
"İzleme ile DOSYA(lar)ı veya standart girdiyi standart çıktı ile birleştirin."
|
||||
|
||||
#: src/main/help.c:598
|
||||
#, c-format
|
||||
msgid "Please report any bugs to: %s"
|
||||
msgstr "Lütfen hataları şu adrese bildirin: %s"
|
||||
|
||||
#: src/main/main.c:230
|
||||
msgid "(input)"
|
||||
msgstr "(giriş)"
|
||||
|
||||
#: src/main/main.c:319
|
||||
msgid "state allocation failed"
|
||||
msgstr "durum tahsisi başarısız oldu"
|
||||
|
||||
#: src/main/options.c:144 src/pv/file.c:324
|
||||
msgid "failed to stat file"
|
||||
msgstr "dosya statüsünde başarısız oldu"
|
||||
|
||||
#: src/main/options.c:158
|
||||
msgid "is a directory"
|
||||
msgstr "bir dizindir"
|
||||
|
||||
#: src/main/options.c:187
|
||||
msgid "failed to generate sysfs filename"
|
||||
msgstr "sysfs dosya adı oluşturulamadı"
|
||||
|
||||
#: src/main/options.c:209
|
||||
msgid "failed to read sysfs size file"
|
||||
msgstr "sysfs boyut dosyası okunamadı"
|
||||
|
||||
#: src/main/options.c:229
|
||||
msgid "failed to open block device"
|
||||
msgstr "blok aygıtı açılamadı"
|
||||
|
||||
#: src/main/options.c:239
|
||||
msgid "failed to determine size of block device"
|
||||
msgstr "blok aygıtının boyutu belirlenemedi"
|
||||
|
||||
#: src/main/options.c:344
|
||||
msgid "option structure allocation failed"
|
||||
msgstr "seçenek yapısı tahsisi başarısız oldu"
|
||||
|
||||
#: src/main/options.c:363
|
||||
msgid "option structure argv allocation failed"
|
||||
msgstr "seçenek yapısı argv tahsisi başarısız oldu"
|
||||
|
||||
#: src/main/options.c:425
|
||||
msgid "integer argument expected"
|
||||
msgstr "tamsayı bağımsız değişkeni bekleniyor"
|
||||
|
||||
#: src/main/options.c:436
|
||||
msgid "numeric argument expected"
|
||||
msgstr "sayısal bağımsız değişken bekleniyor"
|
||||
|
||||
#: src/main/options.c:447
|
||||
msgid "process ID or pid:fd pair expected"
|
||||
msgstr "süreç kimliği (ID) veya pid:fd çifti bekleniyor"
|
||||
|
||||
#: src/main/options.c:454
|
||||
msgid "invalid process ID"
|
||||
msgstr "geçersiz süreç kimliği (ID)"
|
||||
|
||||
#: src/main/options.c:679
|
||||
#, c-format
|
||||
msgid "Try `%s --help' for more information."
|
||||
msgstr "Daha fazla bilgi için `%s --help' seçeneğini deneyin."
|
||||
|
||||
#: src/main/options.c:681
|
||||
#, c-format
|
||||
msgid "Try `%s -h' for more information."
|
||||
msgstr "Daha fazla bilgi için `%s -h' seçeneğini deneyin."
|
||||
|
||||
#: src/main/options.c:712
|
||||
msgid ""
|
||||
"cannot use line mode or transfer modifier options when watching file "
|
||||
"descriptors"
|
||||
msgstr ""
|
||||
"dosya tanımlayıcılarını izlerken satır modu veya aktarım değiştirici "
|
||||
"seçeneklerini kullanamaz"
|
||||
|
||||
#: src/main/options.c:721
|
||||
msgid "cannot use cursor positioning when watching file descriptors"
|
||||
msgstr "dosya tanımlayıcılarını izlerken imleç konumlandırmayı kullanamaz"
|
||||
|
||||
#: src/main/options.c:730
|
||||
msgid "cannot use remote control when watching file descriptors"
|
||||
msgstr "dosya tanımlayıcılarını izlerken uzaktan kumandayı kullanamaz"
|
||||
|
||||
#: src/main/options.c:739
|
||||
msgid "cannot transfer files when watching file descriptors"
|
||||
msgstr "dosya tanımlayıcıları izlenirken dosya aktarılamıyor"
|
||||
|
||||
#: src/main/options.c:754
|
||||
msgid "not available on systems without /proc/self/fdinfo"
|
||||
msgstr "/proc/self/fdinfo olmayan sistemlerde kullanılamaz"
|
||||
|
||||
#: src/main/remote.c:304
|
||||
msgid "message not received"
|
||||
msgstr "mesaj alınamadı"
|
||||
|
||||
#: src/main/remote.c:431
|
||||
msgid "SA_SIGINFO not supported on this system"
|
||||
msgstr "SA_SIGINFO bu sistemde desteklenmiyor"
|
||||
|
||||
#: src/main/version.c:28
|
||||
msgid "License: GPLv3+ <https://www.gnu.org/licenses/gpl-3.0.html>"
|
||||
msgstr "Lisans: GPLv3+ <https://www.gnu.org/licenses/gpl-3.0.html>"
|
||||
|
||||
#: src/main/version.c:29
|
||||
msgid "This is free software: you are free to change and redistribute it."
|
||||
msgstr ""
|
||||
"Bu özgür bir yazılımdır: değiştirmekte ve yeniden dağıtmakta özgürsünüz."
|
||||
|
||||
#: src/main/version.c:30
|
||||
msgid "There is NO WARRANTY, to the extent permitted by law."
|
||||
msgstr "Yasaların izin verdiği ölçüde GARANTİ YOKTUR."
|
||||
|
||||
#: src/main/version.c:32
|
||||
msgid "Project web site"
|
||||
msgstr "Proje web sitesi"
|
||||
|
||||
#: src/pv/cursor.c:61
|
||||
msgid "failed to get terminal name"
|
||||
msgstr "terminal adı alınamadı"
|
||||
|
||||
#: src/pv/cursor.c:106
|
||||
msgid "failed to open lock file"
|
||||
msgstr "lock dosyası açılamadı"
|
||||
|
||||
#: src/pv/cursor.c:139
|
||||
msgid "lock attempt failed"
|
||||
msgstr "kilit denemesi başarısız oldu"
|
||||
|
||||
#: src/pv/cursor.c:400
|
||||
msgid "failed to open terminal"
|
||||
msgstr "terminal açılamadı"
|
||||
|
||||
#: src/pv/display.c:233
|
||||
msgid "yzafpnum kMGTPEZY"
|
||||
msgstr "yzafpnum kMGTPEZY"
|
||||
|
||||
#: src/pv/display.c:251
|
||||
msgid "yzafpnum KMGTPEZY"
|
||||
msgstr "yzafpnum KMGTPEZY"
|
||||
|
||||
#: src/pv/display.c:681 src/pv/transfer.c:1011
|
||||
msgid "buffer allocation failed"
|
||||
msgstr "arabellek tahsisi başarısız oldu"
|
||||
|
||||
#: src/pv/display.c:810
|
||||
msgid "b"
|
||||
msgstr "b"
|
||||
|
||||
#: src/pv/display.c:813 src/pv/transfer.c:602
|
||||
msgid "B"
|
||||
msgstr "B"
|
||||
|
||||
#: src/pv/display.c:857 src/pv/display.c:872 src/pv/display.c:1091
|
||||
#: src/pv/loop.c:549
|
||||
msgid "b/s"
|
||||
msgstr "b/s"
|
||||
|
||||
#: src/pv/display.c:861 src/pv/display.c:876 src/pv/display.c:1095
|
||||
msgid "/s"
|
||||
msgstr "/s"
|
||||
|
||||
#: src/pv/display.c:861 src/pv/display.c:876 src/pv/display.c:1095
|
||||
#: src/pv/loop.c:549
|
||||
msgid "B/s"
|
||||
msgstr "B/s"
|
||||
|
||||
#: src/pv/display.c:904 src/pv/display.c:908
|
||||
msgid "ETA"
|
||||
msgstr "ETA"
|
||||
|
||||
#: src/pv/display.c:974
|
||||
msgid "FIN"
|
||||
msgstr "FIN"
|
||||
|
||||
#: src/pv/file.c:149
|
||||
msgid "failed to seek to start of output"
|
||||
msgstr "çıktının başlangıcına ulaşılamadı"
|
||||
|
||||
#: src/pv/file.c:294
|
||||
msgid "failed to close file"
|
||||
msgstr "dosya kapatılamadı"
|
||||
|
||||
#: src/pv/file.c:317
|
||||
msgid "failed to read file"
|
||||
msgstr "dosya okunamadı"
|
||||
|
||||
#: src/pv/file.c:332
|
||||
msgid "failed to stat output file"
|
||||
msgstr "çıktı dosyası stat edilemedi"
|
||||
|
||||
#: src/pv/file.c:354
|
||||
msgid "input file is output file"
|
||||
msgstr "girdi dosyası çıktı dosyasıdır"
|
||||
|
||||
#: src/pv/file.c:412
|
||||
msgid "(none)"
|
||||
msgstr "(yok)"
|
||||
|
||||
#: src/pv/file.c:414
|
||||
msgid "(stdin)"
|
||||
msgstr "(stdin)"
|
||||
|
||||
#: src/pv/loop.c:548
|
||||
msgid "rate min/avg/max/mdev"
|
||||
msgstr "oran min/ortalama/maks/standart sapma"
|
||||
|
||||
#: src/pv/loop.c:560
|
||||
msgid "rate not measured"
|
||||
msgstr "oran ölçülmedi"
|
||||
|
||||
#: src/pv/loop.c:767 src/pv/loop.c:818 src/pv/loop.c:859 src/pv/watchpid.c:99
|
||||
#: src/pv/watchpid.c:109 src/pv/watchpid.c:120 src/pv/watchpid.c:128
|
||||
#: src/pv/watchpid.c:165 src/pv/watchpid.c:184 src/pv/watchpid.c:192
|
||||
#: src/pv/watchpid.c:202 src/pv/watchpid.c:300 src/pv/watchpid.c:308
|
||||
#: src/pv/watchpid.c:384 src/pv/watchpid.c:405
|
||||
msgid "pid"
|
||||
msgstr "pid"
|
||||
|
||||
#: src/pv/state.c:40
|
||||
msgid "history structure allocation failed"
|
||||
msgstr "geçmiş yapısı tahsisi başarısız oldu"
|
||||
|
||||
#: src/pv/state.c:572 src/pv/state.c:583
|
||||
msgid "file list allocation failed"
|
||||
msgstr "dosya listesi tahsisi başarısız oldu"
|
||||
|
||||
#: src/pv/transfer.c:464
|
||||
msgid "read failed"
|
||||
msgstr "okuma başarısız"
|
||||
|
||||
#: src/pv/transfer.c:487
|
||||
msgid "warning: read errors detected"
|
||||
msgstr "uyarı: okuma hataları tespit edildi"
|
||||
|
||||
#: src/pv/transfer.c:503
|
||||
msgid "file is not seekable"
|
||||
msgstr "dosya aranabilir değil"
|
||||
|
||||
#: src/pv/transfer.c:581
|
||||
msgid "failed to seek past error"
|
||||
msgstr "geçmiş hatayı aramakta başarısız oldu"
|
||||
|
||||
#: src/pv/transfer.c:601
|
||||
msgid "skipped past read error"
|
||||
msgstr "geçmiş okuma hatası atlandı"
|
||||
|
||||
#: src/pv/transfer.c:642
|
||||
msgid "no transfer buffer allocated"
|
||||
msgstr "aktarım arabelleği ayrılmamış"
|
||||
|
||||
#: src/pv/transfer.c:684
|
||||
msgid "failed to set interval timer"
|
||||
msgstr "aralık zamanlayıcısı ayarlanamadı"
|
||||
|
||||
#: src/pv/transfer.c:710
|
||||
msgid "failed to clear interval timer"
|
||||
msgstr "aralık zamanlayıcısı temizlenemedi"
|
||||
|
||||
#: src/pv/transfer.c:740
|
||||
msgid "line position buffer allocation failed"
|
||||
msgstr "satır konumu arabellek tahsisi başarısız oldu"
|
||||
|
||||
#: src/pv/transfer.c:872
|
||||
msgid "write failed"
|
||||
msgstr "yazma başarısız"
|
||||
|
||||
#: src/pv/transfer.c:1109
|
||||
msgid "select call failed"
|
||||
msgstr "seçme çağrısı başarısız oldu"
|
||||
|
||||
#: src/pv/watchpid.c:109 src/pv/watchpid.c:121 src/pv/watchpid.c:130
|
||||
#: src/pv/watchpid.c:184 src/pv/watchpid.c:193 src/pv/watchpid.c:204
|
||||
msgid "fd"
|
||||
msgstr "fd"
|
||||
|
||||
#: src/pv/watchpid.c:130 src/pv/watchpid.c:204
|
||||
msgid "not a regular file or block device"
|
||||
msgstr "normal bir dosya veya blok aygıtı değil"
|
||||
@@ -3,7 +3,7 @@
|
||||
* `configure' script. Include this after config.h and before anything
|
||||
* else.
|
||||
*
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2024 Andrew Wood
|
||||
*
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
@@ -43,5 +43,3 @@ typedef bool _Bool;
|
||||
# define true 1
|
||||
# define __bool_true_false_are_defined 1
|
||||
#endif
|
||||
|
||||
/* EOF */
|
||||
|
||||
@@ -73,6 +73,9 @@
|
||||
/* Define to 1 if you have the <locale.h> header file. */
|
||||
#undef HAVE_LOCALE_H
|
||||
|
||||
/* Define to 1 if you have the <math.h> header file. */
|
||||
#undef HAVE_MATH_H
|
||||
|
||||
/* Define to 1 if you have the `memcpy' function. */
|
||||
#undef HAVE_MEMCPY
|
||||
|
||||
@@ -88,6 +91,9 @@
|
||||
/* Define to 1 if you have the <minix/config.h> header file. */
|
||||
#undef HAVE_MINIX_CONFIG_H
|
||||
|
||||
/* Define to 1 if you have the `mkdir' function. */
|
||||
#undef HAVE_MKDIR
|
||||
|
||||
/* Define to 1 if you have the `nanosleep' function. */
|
||||
#undef HAVE_NANOSLEEP
|
||||
|
||||
@@ -100,15 +106,24 @@
|
||||
/* Define to 1 if you have the `select' function. */
|
||||
#undef HAVE_SELECT
|
||||
|
||||
/* Define to 1 if you have the `setitimer' function. */
|
||||
#undef HAVE_SETITIMER
|
||||
|
||||
/* Define to 1 if you have the `setlocale' function. */
|
||||
#undef HAVE_SETLOCALE
|
||||
|
||||
/* Define to 1 if you have the `setproctitle' function. */
|
||||
#undef HAVE_SETPROCTITLE
|
||||
|
||||
/* Define to 1 if you have the `shmget' function. */
|
||||
#undef HAVE_SHMGET
|
||||
|
||||
/* Define to 1 if you have the `splice' function. */
|
||||
#undef HAVE_SPLICE
|
||||
|
||||
/* Define to 1 if you have the `sqrtl' function. */
|
||||
#undef HAVE_SQRTL
|
||||
|
||||
/* Define to 1 if stdbool.h conforms to C99. */
|
||||
#undef HAVE_STDBOOL_H
|
||||
|
||||
@@ -148,6 +163,9 @@
|
||||
/* Define to 1 if `st_blksize' is a member of `struct stat'. */
|
||||
#undef HAVE_STRUCT_STAT_ST_BLKSIZE
|
||||
|
||||
/* Define to 1 if `st_rdev' is a member of `struct stat'. */
|
||||
#undef HAVE_STRUCT_STAT_ST_RDEV
|
||||
|
||||
/* Define to 1 if you have the `sysconf' function. */
|
||||
#undef HAVE_SYSCONF
|
||||
|
||||
@@ -166,6 +184,9 @@
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#undef HAVE_SYS_STAT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/sysmacros.h> header file. */
|
||||
#undef HAVE_SYS_SYSMACROS_H
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#undef HAVE_SYS_TIME_H
|
||||
|
||||
@@ -211,6 +232,9 @@
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
/* Signal handlers can determine the sending PID */
|
||||
#undef SIGINFO_PROVIDES_PID
|
||||
|
||||
/* Define to 1 if all of the C90 standard headers exist (not just the ones
|
||||
required in a freestanding environment). This macro is provided for
|
||||
backward compatibility; new code need not use it. */
|
||||
|
||||
+34
-25
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Global program option structure and the parsing function prototype.
|
||||
*
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2024 Andrew Wood
|
||||
*
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
@@ -23,8 +23,36 @@ extern "C" {
|
||||
struct opts_s;
|
||||
typedef struct opts_s *opts_t;
|
||||
|
||||
struct opts_s { /* structure describing run-time options */
|
||||
/*
|
||||
* Structure describing run-time options.
|
||||
*
|
||||
* Members are ordered by size to minimise padding.
|
||||
*/
|
||||
struct opts_s {
|
||||
double interval; /* interval between updates */
|
||||
double delay_start; /* delay before first display */
|
||||
/*@keep@*/ const char *program_name; /* name the program is running as */
|
||||
/*@keep@*/ /*@null@*/ char *output; /* fd to write output to */
|
||||
/*@keep@*/ /*@null@*/ char *name; /* display name, if any */
|
||||
/*@keep@*/ /*@null@*/ char *format; /* output format, if any */
|
||||
/*@keep@*/ /*@null@*/ char *pidfile; /* PID file, if any */
|
||||
/*@keep@*/ /*@null@*/ char *store_and_forward_file; /* store and forward file, if any */
|
||||
/*@keep@*/ /*@null@*/ char *extra_display; /* extra display specifier, if any */
|
||||
/*@keep@*/ /*@null@*/ const char **argv; /* array of non-option arguments */
|
||||
size_t lastwritten; /* show N bytes last written */
|
||||
off_t rate_limit; /* rate limit, in bytes per second */
|
||||
size_t buffer_size; /* buffer size, in bytes (0=default) */
|
||||
off_t size; /* total size of data */
|
||||
off_t error_skip_block; /* skip block size, 0 for adaptive */
|
||||
pid_t remote; /* PID of pv to update settings of */
|
||||
unsigned int skip_errors; /* skip read errors counter */
|
||||
pid_t watch_pid; /* process to watch fds of */
|
||||
int watch_fd; /* fd to watch */
|
||||
unsigned int average_rate_window; /* time window in seconds for average rate calculations */
|
||||
unsigned int width; /* screen width */
|
||||
unsigned int height; /* screen height */
|
||||
unsigned int argc; /* number of non-option arguments */
|
||||
unsigned int argv_length; /* allocated array size */
|
||||
bool do_nothing; /* exit-without-doing-anything flag */
|
||||
bool progress; /* progress bar flag */
|
||||
bool timer; /* timer flag */
|
||||
@@ -34,41 +62,24 @@ struct opts_s { /* structure describing run-time options */
|
||||
bool average_rate; /* average rate counter flag */
|
||||
bool bytes; /* bytes transferred flag */
|
||||
bool bits; /* report transfer size in bits */
|
||||
bool decimal_units; /* decimal prefix flag */
|
||||
bool bufpercent; /* transfer buffer percentage flag */
|
||||
size_t lastwritten; /* show N bytes last written */
|
||||
bool force; /* force-if-not-terminal flag */
|
||||
bool cursor; /* whether to use cursor positioning */
|
||||
bool numeric; /* numeric output only */
|
||||
bool wait; /* wait for transfer before display */
|
||||
bool rate_gauge; /* if size unknown, show rate vs max rate */
|
||||
bool linemode; /* count lines instead of bytes */
|
||||
bool null_terminated_lines; /* lines are null-terminated */
|
||||
bool no_display; /* do nothing other than pipe data */
|
||||
off_t rate_limit; /* rate limit, in bytes per second */
|
||||
size_t buffer_size; /* buffer size, in bytes (0=default) */
|
||||
unsigned int remote; /* PID of pv to update settings of */
|
||||
off_t size; /* total size of data */
|
||||
bool no_splice; /* flag set if never to use splice */
|
||||
unsigned int skip_errors; /* skip read errors counter */
|
||||
off_t error_skip_block; /* skip block size, 0 for adaptive */
|
||||
bool stop_at_size; /* set if we stop at "size" bytes */
|
||||
bool sync_after_write; /* set if we sync after every write */
|
||||
bool direct_io; /* set if O_DIRECT is to be used */
|
||||
bool discard_input; /* set to write nothing to stdout */
|
||||
double interval; /* interval between updates */
|
||||
double delay_start; /* delay before first display */
|
||||
pid_t watch_pid; /* process to watch fds of */
|
||||
int watch_fd; /* fd to watch */
|
||||
unsigned int average_rate_window; /* time window in seconds for average rate calculations */
|
||||
unsigned int width; /* screen width */
|
||||
unsigned int height; /* screen height */
|
||||
bool discard_input; /* set to write nothing to output */
|
||||
bool show_stats; /* set to write statistics at the end */
|
||||
bool width_set_manually; /* width was set manually, not detected */
|
||||
bool height_set_manually; /* height was set manually, not detected */
|
||||
/*@keep@*/ /*@null@*/ char *name; /* display name, if any */
|
||||
/*@keep@*/ /*@null@*/ char *format; /* output format, if any */
|
||||
/*@keep@*/ /*@null@*/ char *pidfile; /* PID file, if any */
|
||||
unsigned int argc; /* number of non-option arguments */
|
||||
/*@keep@*/ /*@null@*/ const char **argv; /* array of non-option arguments */
|
||||
unsigned int argv_length; /* allocated array size */
|
||||
};
|
||||
|
||||
/*@-exportlocal@*/
|
||||
@@ -83,5 +94,3 @@ extern bool opts_add_file(opts_t, const char *);
|
||||
#endif
|
||||
|
||||
#endif /* _OPTIONS_H */
|
||||
|
||||
/* EOF */
|
||||
|
||||
+119
-62
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Functions internal to the PV library. Include "config.h" first.
|
||||
*
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2024 Andrew Wood
|
||||
*
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
@@ -49,6 +49,7 @@ typedef enum {
|
||||
#define MAX_WRITE_AT_ONCE (size_t) 524288 /* max to write() in one go */
|
||||
#define TRANSFER_READ_TIMEOUT 0.09L /* seconds to time reads out at */
|
||||
#define TRANSFER_WRITE_TIMEOUT 0.9L /* seconds to time writes out at */
|
||||
#define MAX_LINE_POSITIONS 100000 /* number of lines to remember positions of */
|
||||
|
||||
#define MAXIMISE_BUFFER_FILL 1
|
||||
|
||||
@@ -63,6 +64,9 @@ typedef enum {
|
||||
#define PV_SIZEOF_FILE_FDPATH 4096
|
||||
#define PV_SIZEOF_DISPLAY_NAME 512
|
||||
|
||||
#define PV_DISPLAY_WINDOWTITLE 1
|
||||
#define PV_DISPLAY_PROCESSTITLE 2
|
||||
|
||||
|
||||
/*
|
||||
* Structure for data shared between multiple "pv -c" instances.
|
||||
@@ -75,6 +79,8 @@ struct pvcursorstate_s {
|
||||
|
||||
/*
|
||||
* Structure for holding PV internal state. Opaque outside the PV library.
|
||||
*
|
||||
* In general, members are ordered by size, to minimise padding.
|
||||
*/
|
||||
struct pvstate_s {
|
||||
/******************
|
||||
@@ -91,59 +97,59 @@ struct pvstate_s {
|
||||
* Input files *
|
||||
***************/
|
||||
struct {
|
||||
unsigned int file_count; /* number of input files */
|
||||
/*@only@*/ /*@null@*/ char **filename; /* input filenames */
|
||||
unsigned int file_count; /* number of input files */
|
||||
} files;
|
||||
|
||||
/*******************
|
||||
* Program control *
|
||||
*******************/
|
||||
struct {
|
||||
char default_format[PV_SIZEOF_DEFAULT_FORMAT]; /* default format string */
|
||||
double interval; /* interval between updates */
|
||||
double delay_start; /* delay before first display */
|
||||
/*@only@*/ /*@null@*/ char *name; /* display name */
|
||||
/*@only@*/ /*@null@*/ char *format_string; /* output format string */
|
||||
/*@only@*/ /*@null@*/ char *extra_format_string; /* extra format string */
|
||||
/*@null@*/ char *output_name; /* name of the output, for diagnostics */
|
||||
off_t error_skip_block; /* skip block size, 0 for adaptive */
|
||||
off_t rate_limit; /* rate limit, in bytes per second */
|
||||
size_t target_buffer_size; /* buffer size (0=default) */
|
||||
off_t size; /* total size of data */
|
||||
pid_t watch_pid; /* process to watch fds of */
|
||||
unsigned int skip_errors; /* skip read errors counter */
|
||||
int watch_fd; /* fd to watch */
|
||||
int output_fd; /* fd to write output to */
|
||||
unsigned int average_rate_window; /* time window in seconds for average rate calculations */
|
||||
unsigned int history_interval; /* seconds between each average rate calc history entry */
|
||||
unsigned int width; /* screen width */
|
||||
unsigned int height; /* screen height */
|
||||
unsigned int extra_displays; /* bitmask of extra display destinations */
|
||||
bool force; /* display even if not on terminal */
|
||||
bool cursor; /* use cursor positioning */
|
||||
bool numeric; /* numeric output only */
|
||||
bool wait; /* wait for data before display */
|
||||
bool rate_gauge; /* if size unknown, show rate vs max rate */
|
||||
bool linemode; /* count lines instead of bytes */
|
||||
bool bits; /* report bits instead of bytes */
|
||||
bool decimal_units; /* use decimal prefixes */
|
||||
bool null_terminated_lines; /* lines are null-terminated */
|
||||
bool no_display; /* do nothing other than pipe data */
|
||||
unsigned int skip_errors; /* skip read errors counter */
|
||||
off_t error_skip_block; /* skip block size, 0 for adaptive */
|
||||
bool stop_at_size; /* set if we stop at "size" bytes */
|
||||
bool sync_after_write; /* set if we sync after every write */
|
||||
bool direct_io; /* set if O_DIRECT is to be used */
|
||||
bool direct_io_changed; /* set when direct_io is changed */
|
||||
bool no_splice; /* never use splice() */
|
||||
bool discard_input; /* write nothing to stdout */
|
||||
off_t rate_limit; /* rate limit, in bytes per second */
|
||||
size_t target_buffer_size; /* buffer size (0=default) */
|
||||
off_t size; /* total size of data */
|
||||
double interval; /* interval between updates */
|
||||
double delay_start; /* delay before first display */
|
||||
pid_t watch_pid; /* process to watch fds of */
|
||||
int watch_fd; /* fd to watch */
|
||||
unsigned int average_rate_window; /* time window in seconds for average rate calculations */
|
||||
unsigned int width; /* screen width */
|
||||
unsigned int height; /* screen height */
|
||||
bool show_stats; /* show statistics on exit */
|
||||
bool width_set_manually; /* width was set manually, not detected */
|
||||
bool height_set_manually; /* height was set manually, not detected */
|
||||
/*@only@*/ /*@null@*/ char *name; /* display name */
|
||||
char default_format[PV_SIZEOF_DEFAULT_FORMAT]; /* default format string */
|
||||
/*@only@*/ /*@null@*/ char *format_string; /* output format string */
|
||||
} control;
|
||||
|
||||
/*******************
|
||||
* Signal handling *
|
||||
*******************/
|
||||
struct {
|
||||
int old_stderr; /* see pv_sig_ttou() */
|
||||
bool pv_tty_tostop_added; /* whether we had to set TOSTOP on the terminal */
|
||||
struct timespec tstp_time; /* see pv_sig_tstp() / __cont() */
|
||||
struct timespec toffset; /* total time spent stopped */
|
||||
#ifdef SA_SIGINFO
|
||||
volatile sig_atomic_t rxusr2; /* whether SIGUSR2 was received */
|
||||
volatile pid_t sender; /* PID of sending process for SIGUSR2 */
|
||||
#endif
|
||||
/* old signal handlers to restore in pv_sig_fini(). */
|
||||
struct sigaction old_sigpipe;
|
||||
struct sigaction old_sigttou;
|
||||
@@ -153,8 +159,15 @@ struct pvstate_s {
|
||||
struct sigaction old_sigint;
|
||||
struct sigaction old_sighup;
|
||||
struct sigaction old_sigterm;
|
||||
#ifdef SA_SIGINFO
|
||||
#ifdef SIGINFO_PROVIDES_PID
|
||||
struct sigaction old_sigusr2;
|
||||
#endif
|
||||
struct sigaction old_sigalrm;
|
||||
struct timespec tstp_time; /* see pv_sig_tstp() / __cont() */
|
||||
struct timespec toffset; /* total time spent stopped */
|
||||
#ifdef SIGINFO_PROVIDES_PID
|
||||
volatile sig_atomic_t rxusr2; /* whether SIGUSR2 was received */
|
||||
volatile pid_t sender; /* PID of sending process for SIGUSR2 */
|
||||
#endif
|
||||
} signal;
|
||||
|
||||
@@ -165,72 +178,98 @@ struct pvstate_s {
|
||||
volatile sig_atomic_t reparse_display; /* whether to re-check format string */
|
||||
volatile sig_atomic_t terminal_resized; /* whether we need to get term size again */
|
||||
volatile sig_atomic_t trigger_exit; /* whether we need to abort right now */
|
||||
volatile sig_atomic_t clear_tty_tostop_on_exit; /* whether to clear tty TOSTOP on exit */
|
||||
volatile sig_atomic_t suspend_stderr; /* whether writing to stderr is suspended */
|
||||
volatile sig_atomic_t skip_next_sigcont; /* whether to ignore the next SIGCONT */
|
||||
volatile sig_atomic_t pipe_closed; /* whether the output pipe was closed */
|
||||
} flag;
|
||||
|
||||
/*****************
|
||||
* Display state *
|
||||
*****************/
|
||||
struct {
|
||||
struct pvdisplay_s {
|
||||
|
||||
struct { /* format string broken into display components */
|
||||
size_t str_start; /* for strings: start offset */
|
||||
size_t str_length; /* for strings: length */
|
||||
pv_display_component type; /* type of display component */
|
||||
} format[PV_FORMAT_ARRAY_MAX];
|
||||
|
||||
struct { /* display components */
|
||||
char content[PV_SIZEOF_COMPONENT_STR]; /* string to display */
|
||||
size_t length; /* number of bytes in string */
|
||||
bool required; /* true if included in format */
|
||||
} component[PV_COMPONENT__MAX];
|
||||
|
||||
char lastoutput_buffer[PV_SIZEOF_LASTOUTPUT_BUFFER];
|
||||
|
||||
/*@only@*/ /*@null@*/ char *display_buffer; /* buffer for display string */
|
||||
size_t display_buffer_size; /* size allocated to display buffer */
|
||||
size_t display_string_len; /* length of string in display buffer */
|
||||
off_t initial_offset; /* offset when first opened (when watching fds) */
|
||||
size_t lastoutput_length; /* number of last-output bytes to show */
|
||||
|
||||
size_t format_segment_count; /* number of format string segments */
|
||||
|
||||
unsigned int prev_screen_width; /* screen width last time we were called */
|
||||
bool display_visible; /* set once anything written to terminal */
|
||||
|
||||
int percentage; /* transfer percentage completion */
|
||||
} display;
|
||||
|
||||
/* Extra display for alternate outputs like a window title. */
|
||||
struct pvdisplay_s extra_display;
|
||||
|
||||
/************************************
|
||||
* Calculated state of the transfer *
|
||||
************************************/
|
||||
struct {
|
||||
long double transfer_rate; /* calculated transfer rate */
|
||||
long double average_rate; /* calculated average transfer rate */
|
||||
|
||||
long double prev_elapsed_sec; /* elapsed sec at which rate last calculated */
|
||||
long double prev_rate; /* last calculated instantaneous transfer rate */
|
||||
long double prev_trans; /* bytes transferred since last rate calculation */
|
||||
long double prev_trans; /* amount transferred since last rate calculation */
|
||||
long double current_avg_rate; /* current average rate over last history intervals */
|
||||
|
||||
long double rate_min; /* minimum measured transfer rate */
|
||||
long double rate_max; /* maximum measured transfer rate */
|
||||
long double rate_sum; /* sum of all measured transfer rates */
|
||||
long double ratesquared_sum; /* sum of the squares of each transfer rate */
|
||||
unsigned long measurements_taken; /* how many times the rate was measured */
|
||||
|
||||
/* Keep track of progress over last intervals to compute current average rate. */
|
||||
/*@null@*/ struct { /* state at previous intervals (circular buffer) */
|
||||
long double elapsed_sec; /* time since start of transfer */
|
||||
off_t total_bytes; /* amount transferred by that time */
|
||||
off_t transferred; /* amount transferred by that time */
|
||||
} *history;
|
||||
size_t history_len; /* total size of history array */
|
||||
int history_interval; /* seconds between each history entry */
|
||||
size_t history_first; /* index of oldest entry */
|
||||
size_t history_last; /* index of newest entry */
|
||||
long double current_avg_rate; /* current average rate over last history intervals */
|
||||
|
||||
off_t initial_offset; /* offset when first opened (when watching fds) */
|
||||
off_t prev_transferred; /* total amount transferred when called last time */
|
||||
|
||||
size_t lastoutput_length; /* number of last-output bytes to show */
|
||||
char lastoutput_buffer[PV_SIZEOF_LASTOUTPUT_BUFFER];
|
||||
|
||||
size_t format_segment_count; /* number of format string segments */
|
||||
struct { /* format string broken into display components */
|
||||
pv_display_component type; /* type of display component */
|
||||
size_t str_start; /* for strings: start offset */
|
||||
size_t str_length; /* for strings: length */
|
||||
} format[PV_FORMAT_ARRAY_MAX];
|
||||
|
||||
struct { /* display components */
|
||||
bool required; /* true if included in format */
|
||||
char content[PV_SIZEOF_COMPONENT_STR]; /* string to display */
|
||||
size_t length; /* number of bytes in string */
|
||||
} component[PV_COMPONENT__MAX];
|
||||
|
||||
} display;
|
||||
int percentage; /* transfer percentage completion */
|
||||
} calc;
|
||||
|
||||
/********************
|
||||
* Cursor/IPC state *
|
||||
********************/
|
||||
struct {
|
||||
char lock_file[PV_SIZEOF_CRS_LOCK_FILE];
|
||||
#ifdef HAVE_IPC
|
||||
/*@keep@*/ /*@null@*/ struct pvcursorstate_s *shared; /* data shared between instances */
|
||||
int shmid; /* ID of our shared memory segment */
|
||||
int pvcount; /* number of `pv' processes in total */
|
||||
int pvmax; /* highest number of `pv's seen */
|
||||
/*@keep@*/ /*@null@*/ struct pvcursorstate_s *shared; /* data shared between instances */
|
||||
int y_lastread; /* last value of _y_top seen */
|
||||
int y_offset; /* our Y offset from this top position */
|
||||
int needreinit; /* counter if we need to reinit cursor pos */
|
||||
bool noipc; /* set if we can't use IPC */
|
||||
#endif /* HAVE_IPC */
|
||||
int lock_fd; /* fd of lockfile, -1 if none open */
|
||||
char lock_file[PV_SIZEOF_CRS_LOCK_FILE];
|
||||
int y_start; /* our initial Y coordinate */
|
||||
#ifdef HAVE_IPC
|
||||
bool noipc; /* set if we can't use IPC */
|
||||
#endif /* HAVE_IPC */
|
||||
} cursor;
|
||||
|
||||
/*******************
|
||||
@@ -252,11 +291,27 @@ struct pvstate_s {
|
||||
* will always be less than or equal to read_position.
|
||||
*/
|
||||
struct {
|
||||
long double elapsed_seconds; /* how long we have been transferring data for */
|
||||
/*@only@*/ /*@null@*/ char *transfer_buffer; /* data transfer buffer */
|
||||
size_t buffer_size; /* size of buffer */
|
||||
size_t read_position; /* amount of data in buffer */
|
||||
size_t write_position; /* buffered data written */
|
||||
|
||||
ssize_t to_write; /* max to write this time around */
|
||||
ssize_t written; /* bytes sent to stdout this time */
|
||||
|
||||
size_t written_but_not_consumed; /* bytes in the output pipe, unread */
|
||||
|
||||
off_t total_written; /* total bytes or lines written */
|
||||
off_t transferred; /* amount transferred (written - unconsumed) */
|
||||
|
||||
/* Keep track of line positions to backtrack written_but_not_consumed. */
|
||||
/*@null@*/ off_t *line_positions; /* line separator write positions (circular buffer) */
|
||||
size_t line_positions_capacity; /* total size of line position array */
|
||||
size_t line_positions_length; /* number of positions stored in array */
|
||||
size_t line_positions_head; /* index to use for next position */
|
||||
off_t last_output_position; /* write position last sent to output */
|
||||
|
||||
/*
|
||||
* While reading from a file descriptor we keep track of how
|
||||
* many times in a row we've seen errors
|
||||
@@ -272,9 +327,9 @@ struct pvstate_s {
|
||||
*
|
||||
* This way, we're treating each input file separately.
|
||||
*/
|
||||
int last_read_skip_fd;
|
||||
off_t read_errors_in_a_row;
|
||||
bool read_error_warning_shown;
|
||||
int last_read_skip_fd;
|
||||
/* read_error_warning_shown is defined below. */
|
||||
#ifdef HAVE_SPLICE
|
||||
/*
|
||||
* These variables are used to keep track of whether
|
||||
@@ -287,15 +342,12 @@ struct pvstate_s {
|
||||
int splice_failed_fd;
|
||||
bool splice_used;
|
||||
#endif
|
||||
ssize_t to_write; /* max to write this time around */
|
||||
ssize_t written; /* bytes sent to stdout this time */
|
||||
bool read_error_warning_shown;
|
||||
} transfer;
|
||||
};
|
||||
|
||||
|
||||
struct pvwatchfd_s {
|
||||
pid_t watch_pid; /* PID to watch */
|
||||
int watch_fd; /* fd to watch, -1 = not displayed */
|
||||
#ifdef __APPLE__
|
||||
#else
|
||||
char file_fdinfo[PV_SIZEOF_FILE_FDINFO]; /* path to /proc fdinfo file */
|
||||
@@ -309,18 +361,25 @@ struct pvwatchfd_s {
|
||||
off_t position; /* position last seen at */
|
||||
struct timespec start_time; /* time we started watching the fd */
|
||||
/*@null@*/ pvstate_t state; /* state object for flags and display */
|
||||
pid_t watch_pid; /* PID to watch */
|
||||
int watch_fd; /* fd to watch, -1 = not displayed */
|
||||
};
|
||||
typedef struct pvwatchfd_s *pvwatchfd_t;
|
||||
|
||||
typedef struct pvdisplay_s *pvdisplay_t;
|
||||
|
||||
void pv_error(pvstate_t, char *, ...);
|
||||
|
||||
int pv_main_loop(pvstate_t);
|
||||
void pv_display(pvstate_t, long double, off_t, off_t);
|
||||
void pv_calculate_transfer_rate(pvstate_t, bool);
|
||||
bool pv_format(pvstate_t, /*@null@*/ const char *, pvdisplay_t, bool, bool);
|
||||
void pv_display(pvstate_t, bool);
|
||||
ssize_t pv_transfer(pvstate_t, int, bool *, bool *, off_t, long *);
|
||||
int pv_next_file(pvstate_t, unsigned int, int);
|
||||
/*@out@*/ const char *pv_current_file_name(pvstate_t);
|
||||
|
||||
void pv_write_retry(int, const char *, size_t);
|
||||
void pv_tty_write(pvstate_t, const char *, size_t);
|
||||
|
||||
void pv_crs_fini(pvstate_t);
|
||||
void pv_crs_init(pvstate_t);
|
||||
@@ -349,5 +408,3 @@ void pv_watchpid_setname(pvstate_t, pvwatchfd_t);
|
||||
#endif
|
||||
|
||||
#endif /* _PV_INTERNAL_H */
|
||||
|
||||
/* EOF */
|
||||
|
||||
+41
-8
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Functions used across the program.
|
||||
*
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2024 Andrew Wood
|
||||
*
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
@@ -23,6 +23,18 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Exit status bitmask values.
|
||||
*/
|
||||
#define PV_ERROREXIT_REMOTE_OR_PID 1
|
||||
#define PV_ERROREXIT_SAF 1 /* store and forward error */
|
||||
#define PV_ERROREXIT_ACCESS 2
|
||||
#define PV_ERROREXIT_OUROBOROS 4
|
||||
#define PV_ERROREXIT_TRANSITION 8
|
||||
#define PV_ERROREXIT_TRANSFER 16
|
||||
#define PV_ERROREXIT_SIGNAL 32
|
||||
#define PV_ERROREXIT_MEMORY 64
|
||||
|
||||
/*
|
||||
* Opaque structure for PV internal state.
|
||||
*/
|
||||
@@ -49,15 +61,17 @@ typedef enum {
|
||||
extern double pv_getnum_interval(const char *);
|
||||
|
||||
/*
|
||||
* Return the given string converted to an off_t, for use as a size.
|
||||
* Return the given string converted to an off_t, for use as a size,
|
||||
* optionally interpreting suffixes in decimal units (multiples of 1000)
|
||||
* instead of multiples of 1024.
|
||||
*/
|
||||
extern off_t pv_getnum_size(const char *);
|
||||
extern off_t pv_getnum_size(const char *, bool);
|
||||
|
||||
/*
|
||||
* Return the given string converted to an unsigned integer, for use as a
|
||||
* count such as screen width.
|
||||
*/
|
||||
extern unsigned int pv_getnum_count(const char *);
|
||||
extern unsigned int pv_getnum_count(const char *, bool);
|
||||
|
||||
/*
|
||||
* Return true if the given string is a number of the given type. NB an
|
||||
@@ -65,6 +79,13 @@ extern unsigned int pv_getnum_count(const char *);
|
||||
*/
|
||||
extern bool pv_getnum_check(const char *, pv_numtype);
|
||||
|
||||
/*
|
||||
* Return an integer representing the first amount as a percentage of the
|
||||
* second total, i.e. 100*amount/total. If the second value, the total, is
|
||||
* zero or less, return 0.
|
||||
*/
|
||||
extern int pv_percentage(off_t, const off_t);
|
||||
|
||||
/*
|
||||
* String handling wrappers.
|
||||
*/
|
||||
@@ -143,6 +164,11 @@ void pv_nanosleep(long long);
|
||||
*/
|
||||
extern /*@null@*/ /*@only@*/ pvstate_t pv_state_alloc(const char *);
|
||||
|
||||
/*
|
||||
* Clear the calculated parts of a state structure.
|
||||
*/
|
||||
extern void pv_state_reset(pvstate_t state);
|
||||
|
||||
/*
|
||||
* Set the formatting string, given a set of old-style formatting options.
|
||||
*/
|
||||
@@ -159,11 +185,14 @@ extern void pv_state_set_format(pvstate_t state, bool progress,
|
||||
*/
|
||||
extern void pv_state_force_set(pvstate_t, bool);
|
||||
extern void pv_state_cursor_set(pvstate_t, bool);
|
||||
extern void pv_state_show_stats_set(pvstate_t, bool);
|
||||
extern void pv_state_numeric_set(pvstate_t, bool);
|
||||
extern void pv_state_wait_set(pvstate_t, bool);
|
||||
extern void pv_state_delay_start_set(pvstate_t, double);
|
||||
extern void pv_state_rate_gauge_set(pvstate_t, bool);
|
||||
extern void pv_state_linemode_set(pvstate_t, bool);
|
||||
extern void pv_state_bits_set(pvstate_t, bool);
|
||||
extern void pv_state_decimal_units_set(pvstate_t, bool);
|
||||
extern void pv_state_null_terminated_lines_set(pvstate_t, bool);
|
||||
extern void pv_state_no_display_set(pvstate_t, bool);
|
||||
extern void pv_state_skip_errors_set(pvstate_t, unsigned int);
|
||||
@@ -181,8 +210,10 @@ extern void pv_state_width_set(pvstate_t, unsigned int, bool);
|
||||
extern void pv_state_height_set(pvstate_t, unsigned int, bool);
|
||||
extern void pv_state_name_set(pvstate_t, /*@null@*/ const char *);
|
||||
extern void pv_state_format_string_set(pvstate_t, /*@null@*/ const char *);
|
||||
extern void pv_state_extra_display_set(pvstate_t, /*@null@*/ const char *);
|
||||
extern void pv_state_watch_pid_set(pvstate_t, pid_t);
|
||||
extern void pv_state_watch_fd_set(pvstate_t, int);
|
||||
extern void pv_state_output_set(pvstate_t, int, const char *);
|
||||
extern void pv_state_average_rate_window_set(pvstate_t, unsigned int);
|
||||
|
||||
extern void pv_state_inputfiles(pvstate_t, unsigned int, const char **);
|
||||
@@ -207,7 +238,7 @@ extern off_t pv_calc_total_size(pvstate_t);
|
||||
*/
|
||||
extern void pv_sig_init(pvstate_t);
|
||||
|
||||
#ifdef SA_SIGINFO
|
||||
#ifdef SIGINFO_PROVIDES_PID
|
||||
/*
|
||||
* Return true if SIGUSR2 has been received, and indicate the sender.
|
||||
*/
|
||||
@@ -239,6 +270,10 @@ extern void pv_sig_fini(pvstate_t);
|
||||
*/
|
||||
extern void pv_state_free(/*@only@*/ pvstate_t);
|
||||
|
||||
#if ! HAVE_SETPROCTITLE
|
||||
void initproctitle(int, char **);
|
||||
void setproctitle(const char *, ...);
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_DEBUGGING
|
||||
# if __STDC_VERSION__ < 199901L && !defined(__func__)
|
||||
@@ -250,7 +285,7 @@ extern void pv_state_free(/*@only@*/ pvstate_t);
|
||||
# endif
|
||||
# define debug(x,...) debugging_output(__func__, __FILE__, __LINE__, x, __VA_ARGS__)
|
||||
#else
|
||||
# define debug(x,...) do { } while (0)
|
||||
# define debug(x,...) /*@-noeffect@*/ do { } while (0) /*@+noeffect@*/
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -269,5 +304,3 @@ void debugging_output(const char *, const char *, int, const char *, ...);
|
||||
#endif
|
||||
|
||||
#endif /* _PV_H */
|
||||
|
||||
/* EOF */
|
||||
|
||||
+17
-9
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Output debugging information.
|
||||
*
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2024 Andrew Wood
|
||||
*
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
@@ -63,8 +63,18 @@ void debugging_output(const char *function, const char *file, int line, const ch
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that here we use gmtime() rather than localtime(), otherwise
|
||||
* we can get stuck in signal handlers - testing with "strace"
|
||||
* showed many cases where "pv </dev/zero | cat >/dev/null" being
|
||||
* paused and backgrounded would cause pv to be stuck in
|
||||
* futex_wait() inside a pv_sig_alrm() inside a pv_sig_cont(). The
|
||||
* backtrace mentioned many time zone conversion steps, and all of
|
||||
* that goes away with gmtime().
|
||||
*/
|
||||
|
||||
(void) time(&t);
|
||||
tm = localtime(&t);
|
||||
tm = gmtime(&t);
|
||||
tbuf[0] = '\0';
|
||||
if (0 == strftime(tbuf, sizeof(tbuf), "%Y-%m-%d %H:%M:%S", tm)) {
|
||||
tbuf[0] = '\0';
|
||||
@@ -91,7 +101,7 @@ void debugging_output(const char *function, const char *file, int line, const ch
|
||||
/*
|
||||
* Stub debugging destination function.
|
||||
*/
|
||||
void debugging_output_destination( __attribute__((unused))
|
||||
void debugging_output_destination( /*@unused@ */ __attribute__((unused))
|
||||
const char *filename)
|
||||
{
|
||||
}
|
||||
@@ -99,14 +109,12 @@ void debugging_output_destination( __attribute__((unused))
|
||||
/*
|
||||
* Stub debugging output function.
|
||||
*/
|
||||
void debugging_output( __attribute__((unused))
|
||||
const char *function, __attribute__((unused))
|
||||
const char *file, __attribute__((unused))
|
||||
int line, __attribute__((unused))
|
||||
void debugging_output( /*@unused@ */ __attribute__((unused))
|
||||
const char *function, /*@unused@ */ __attribute__((unused))
|
||||
const char *file, /*@unused@ */ __attribute__((unused))
|
||||
int line, /*@unused@ */ __attribute__((unused))
|
||||
const char *format, ...)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* ENABLE_DEBUGGING */
|
||||
|
||||
/* EOF */
|
||||
|
||||
+30
-16
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Output command-line help to stdout.
|
||||
*
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2024 Andrew Wood
|
||||
*
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
@@ -298,15 +298,9 @@ void display_help(void)
|
||||
{ "-a", "--average-rate", NULL,
|
||||
N_("show data transfer average rate counter"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "-m", "--average-rate-window", N_("SEC"),
|
||||
N_("compute average rate over past SEC seconds (default 30s)"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "-b", "--bytes", NULL,
|
||||
N_("show number of bytes transferred"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "-8", "--bits", NULL,
|
||||
N_("show number of bits transferred"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "-T", "--buffer-percent", NULL,
|
||||
N_("show percentage of transfer buffer in use"),
|
||||
{ 0, 0, 0, 0} },
|
||||
@@ -323,6 +317,12 @@ void display_help(void)
|
||||
N_("do not output any transfer information at all"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "", NULL, NULL, NULL, { 0, 0, 0, 0} },
|
||||
{ "-8", "--bits", NULL,
|
||||
N_("show number of bits transferred"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "-k", "--si", NULL,
|
||||
N_("treat suffixes as multiples of 1000 rather than 1024"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "-W", "--wait", NULL,
|
||||
N_("display nothing until first byte transferred"),
|
||||
{ 0, 0, 0, 0} },
|
||||
@@ -332,6 +332,9 @@ void display_help(void)
|
||||
{ "-s", "--size", N_("SIZE"),
|
||||
N_("set estimated data size to SIZE bytes"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "-g", "--gauge", NULL,
|
||||
N_("if size unknown, show rate vs max rate"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "-l", "--line-mode", NULL,
|
||||
N_("count lines instead of bytes"),
|
||||
{ 0, 0, 0, 0} },
|
||||
@@ -341,6 +344,9 @@ void display_help(void)
|
||||
{ "-i", "--interval", N_("SEC"),
|
||||
N_("update every SEC seconds"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "-m", "--average-rate-window", N_("SEC"),
|
||||
N_("compute average rate over past SEC seconds (default 30s)"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "-w", "--width", N_("WIDTH"),
|
||||
N_("assume terminal is WIDTH characters wide"),
|
||||
{ 0, 0, 0, 0} },
|
||||
@@ -350,6 +356,12 @@ void display_help(void)
|
||||
{ "-N", "--name", N_("NAME"),
|
||||
N_("prefix visual information with NAME"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "-x", "--extra-display", N_("SPEC"),
|
||||
N_("also send progress to SPEC"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "-v", "--stats", NULL,
|
||||
N_("output transfer statistics at the end"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "-f", "--force", NULL,
|
||||
N_("output even if standard error is not a terminal"),
|
||||
{ 0, 0, 0, 0} },
|
||||
@@ -357,6 +369,9 @@ void display_help(void)
|
||||
N_("use cursor positioning escape sequences"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "", NULL, NULL, NULL, { 0, 0, 0, 0} },
|
||||
{ "-o", "--output", N_("FILE"),
|
||||
N_("write output to FILE instead of stdout"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "-L", "--rate-limit", N_("RATE"),
|
||||
N_("limit transfer to RATE bytes per second"),
|
||||
{ 0, 0, 0, 0} },
|
||||
@@ -384,20 +399,21 @@ void display_help(void)
|
||||
{ "-X", "--discard", NULL,
|
||||
N_("discard input instead of writing to output"),
|
||||
{ 0, 0, 0, 0} },
|
||||
#ifdef SA_SIGINFO
|
||||
{ "-U", "--store-and-forward", N_("FILE"),
|
||||
N_("write all input to FILE before writing to output"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "-d", "--watchfd", N_("PID[:FD]"),
|
||||
N_("watch file FD opened by process PID"),
|
||||
{ 0, 0, 0, 0} },
|
||||
#ifdef SIGINFO_PROVIDES_PID
|
||||
{ "-R", "--remote", N_("PID"),
|
||||
N_("update settings of process PID"),
|
||||
{ 0, 0, 0, 0} },
|
||||
#endif /* SA_SIGINFO */
|
||||
#endif /* SIGINFO_PROVIDES_PID */
|
||||
{ "", NULL, NULL, NULL, { 0, 0, 0, 0} },
|
||||
{ "-P", "--pidfile", N_("FILE"),
|
||||
N_("save process ID in FILE"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "", NULL, NULL, NULL, { 0, 0, 0, 0} },
|
||||
{ "-d", "--watchfd", N_("PID[:FD]"),
|
||||
N_("watch file FD opened by process PID"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "", NULL, NULL, NULL, { 0, 0, 0, 0} },
|
||||
{ "-h", "--help", NULL,
|
||||
N_("show this help and exit"),
|
||||
{ 0, 0, 0, 0} },
|
||||
@@ -592,5 +608,3 @@ void display_help(void)
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
||||
+315
-118
@@ -2,7 +2,7 @@
|
||||
* Main program entry point - read the command line options, then perform
|
||||
* the appropriate actions.
|
||||
*
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2024 Andrew Wood
|
||||
*
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
@@ -11,9 +11,6 @@
|
||||
#include "options.h"
|
||||
#include "pv.h"
|
||||
|
||||
/* We do not set this because it breaks "dd" - see below. */
|
||||
/* #undef MAKE_STDOUT_NONBLOCKING */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
@@ -28,6 +25,249 @@ int pv_remote_set(opts_t, pvstate_t);
|
||||
void pv_remote_init(void);
|
||||
void pv_remote_fini(void);
|
||||
|
||||
/*
|
||||
* Write a PID file, returning nonzero on error. Write it atomically, such
|
||||
* that the file either exists and contains the PID, or is not updated at
|
||||
* all. This is done by writing to a temporary file in the same directory
|
||||
* first, and then renaming the temporary file to the target name.
|
||||
*/
|
||||
static int pv__write_pidfile(opts_t opts)
|
||||
{
|
||||
char *pidfile_tmp_name;
|
||||
size_t pidfile_tmp_bufsize;
|
||||
int pidfile_tmp_fd;
|
||||
FILE *pidfile_tmp_fptr;
|
||||
mode_t prev_umask;
|
||||
const char *pidfile_template = "%s.XXXXXX";
|
||||
|
||||
if (NULL == opts->pidfile)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* The buffer needs to be long enough to hold the pidfile with the
|
||||
* mkstemp template ".XXXXXX" after it. The "%s" of our
|
||||
* pidfile_template adds 2 extra bytes to the length, of which we
|
||||
* need 1 byte for the terminating \0, so we subtract 1 byte more to
|
||||
* get the exact amount of space we need.
|
||||
*/
|
||||
pidfile_tmp_bufsize = strlen(pidfile_template) + strlen(opts->pidfile) - 1; /* flawfinder: ignore */
|
||||
|
||||
/*
|
||||
* flawfinder rationale: flawfinder never likes strlen() in case
|
||||
* it's called on a string that isn't \0 terminated. We have to use
|
||||
* strlen() to find the length of opts->pidfile, so have to trust
|
||||
* that the arguments in argv[] were \0 terminated. We can be sure
|
||||
* that pidfile_template is \0 terminated because we've set it to a
|
||||
* constant value. So we tell flawfinder to skip this check here.
|
||||
*/
|
||||
pidfile_tmp_name = malloc(pidfile_tmp_bufsize);
|
||||
if (NULL == pidfile_tmp_name) {
|
||||
fprintf(stderr, "%s: %s\n", opts->program_name, strerror(errno));
|
||||
return PV_ERROREXIT_REMOTE_OR_PID;
|
||||
}
|
||||
memset(pidfile_tmp_name, 0, pidfile_tmp_bufsize);
|
||||
(void) pv_snprintf(pidfile_tmp_name, pidfile_tmp_bufsize, pidfile_template, opts->pidfile);
|
||||
|
||||
/*@-type@ *//* splint doesn't like mode_t */
|
||||
prev_umask = umask(0000); /* flawfinder: ignore */
|
||||
(void) umask(prev_umask | 0133); /* flawfinder: ignore */
|
||||
|
||||
/*@-unrecog@ *//* splint doesn't know mkstemp() */
|
||||
pidfile_tmp_fd = mkstemp(pidfile_tmp_name); /* flawfinder: ignore */
|
||||
/*@+unrecog@ */
|
||||
if (pidfile_tmp_fd < 0) {
|
||||
fprintf(stderr, "%s: %s: %s\n", opts->program_name, pidfile_tmp_name, strerror(errno));
|
||||
(void) umask(prev_umask); /* flawfinder: ignore */
|
||||
free(pidfile_tmp_name);
|
||||
return PV_ERROREXIT_REMOTE_OR_PID;
|
||||
}
|
||||
|
||||
(void) umask(prev_umask); /* flawfinder: ignore */
|
||||
|
||||
/*
|
||||
* flawfinder rationale (umask, mkstemp) - flawfinder
|
||||
* recommends setting the most restrictive umask possible
|
||||
* when calling mkstemp(), so this is what we have done.
|
||||
*
|
||||
* We get the original umask and OR it with 0133 to make
|
||||
* sure new files will be at least chmod 644. Then we put
|
||||
* the umask back to what it was, after creating the
|
||||
* temporary file.
|
||||
*/
|
||||
|
||||
/*@+type@ */
|
||||
|
||||
pidfile_tmp_fptr = fdopen(pidfile_tmp_fd, "w");
|
||||
if (NULL == pidfile_tmp_fptr) {
|
||||
fprintf(stderr, "%s: %s: %s\n", opts->program_name, pidfile_tmp_name, strerror(errno));
|
||||
(void) close(pidfile_tmp_fd);
|
||||
(void) remove(pidfile_tmp_name);
|
||||
free(pidfile_tmp_name);
|
||||
return PV_ERROREXIT_REMOTE_OR_PID;
|
||||
}
|
||||
|
||||
fprintf(pidfile_tmp_fptr, "%d\n", getpid());
|
||||
if (0 != fclose(pidfile_tmp_fptr)) {
|
||||
fprintf(stderr, "%s: %s: %s\n", opts->program_name, opts->pidfile, strerror(errno));
|
||||
}
|
||||
|
||||
if (rename(pidfile_tmp_name, opts->pidfile) < 0) {
|
||||
fprintf(stderr, "%s: %s: %s\n", opts->program_name, opts->pidfile, strerror(errno));
|
||||
(void) remove(pidfile_tmp_name);
|
||||
}
|
||||
|
||||
free(pidfile_tmp_name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set the output file, if applicable. Returns nonzero on error.
|
||||
*/
|
||||
static int pv__set_output(pvstate_t state, opts_t opts, /*@null@ */ const char *output_file)
|
||||
{
|
||||
int output_fd;
|
||||
|
||||
if ((NULL == state) || (NULL == opts))
|
||||
return 0;
|
||||
|
||||
if (NULL == output_file || 0 == strcmp(output_file, "-")) {
|
||||
pv_state_output_set(state, STDOUT_FILENO, "(stdout)");
|
||||
return 0;
|
||||
}
|
||||
|
||||
output_fd = open(output_file, O_WRONLY | O_CREAT | O_TRUNC, 0600); /* flawfinder: ignore */
|
||||
/*
|
||||
* flawfinder rationale: the output filename has been
|
||||
* explicitly provided, and in many cases the operator will
|
||||
* want to write to device files and other special
|
||||
* destinations, so there is no sense-checking we can do to
|
||||
* make this safer.
|
||||
*/
|
||||
if (output_fd < 0) {
|
||||
fprintf(stderr, "%s: %s: %s\n", opts->program_name, output_file, strerror(errno));
|
||||
return PV_ERROREXIT_ACCESS;
|
||||
}
|
||||
|
||||
pv_state_output_set(state, output_fd, output_file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Run in store-and-forward mode: run the main loop once with the output
|
||||
* forced to the store-and-forward file (taking care of creation and removal
|
||||
* of a temporary file if "-" was specified); then run the main loop again
|
||||
* with the input file list forced to be just the store-and-forward file.
|
||||
* Returns nonzero on error.
|
||||
*/
|
||||
static int pv__store_and_forward(pvstate_t state, opts_t opts, bool can_have_eta)
|
||||
{
|
||||
char tmp_filename[4096]; /* flawfinder: ignore */
|
||||
bool use_temporary_file;
|
||||
char *real_store_and_forward_file;
|
||||
int retcode;
|
||||
|
||||
/* flawfinder: zeroed with memset and bounded by pv_snprintf. */
|
||||
|
||||
if ((NULL == state) || (NULL == opts) || (NULL == opts->store_and_forward_file))
|
||||
return 0;
|
||||
|
||||
memset(tmp_filename, 0, sizeof(tmp_filename));
|
||||
|
||||
use_temporary_file = false;
|
||||
if (0 == strcmp(opts->store_and_forward_file, "-"))
|
||||
use_temporary_file = true;
|
||||
|
||||
/*
|
||||
* Create a temporary file if the specified file was "-".
|
||||
*/
|
||||
if (use_temporary_file) {
|
||||
char *tmpdir;
|
||||
int tmp_fd;
|
||||
|
||||
tmpdir = (char *) getenv("TMPDIR"); /* flawfinder: ignore */
|
||||
if ((NULL == tmpdir) || ('\0' == tmpdir[0]))
|
||||
tmpdir = (char *) getenv("TMP"); /* flawfinder: ignore */
|
||||
if ((NULL == tmpdir) || ('\0' == tmpdir[0]))
|
||||
tmpdir = "/tmp";
|
||||
|
||||
/*
|
||||
* flawfinder rationale: null and zero-size values of $TMPDIR and
|
||||
* $TMP are rejected, and the destination buffer is bounded.
|
||||
*/
|
||||
|
||||
(void) pv_snprintf(tmp_filename, sizeof(tmp_filename), "%s/pv.XXXXXX", tmpdir);
|
||||
/*@-unrecog@ *//* splint doesn't know mkstemp() */
|
||||
tmp_fd = mkstemp(tmp_filename); /* flawfinder: ignore */
|
||||
/*@+unrecog@ */
|
||||
if (tmp_fd < 0) {
|
||||
fprintf(stderr, "%s: %s: %s\n", opts->program_name, tmp_filename, strerror(errno));
|
||||
return PV_ERROREXIT_SAF;
|
||||
}
|
||||
(void) close(tmp_fd);
|
||||
}
|
||||
|
||||
/*
|
||||
* Real store-and-forward file: either the one we were given, or the
|
||||
* temporary file we created if we were given "-".
|
||||
*/
|
||||
real_store_and_forward_file = use_temporary_file ? tmp_filename : opts->store_and_forward_file;
|
||||
|
||||
/*
|
||||
* First, set the output file to the store-and-forward file.
|
||||
*/
|
||||
debug("%s: %s", "setting output to store-and-forward file", real_store_and_forward_file);
|
||||
retcode = pv__set_output(state, opts, real_store_and_forward_file);
|
||||
if (0 != retcode)
|
||||
goto end_store_and_forward;
|
||||
|
||||
/* Reset the formatting to set the displayed name to "(input)". */
|
||||
/*@-mustfreefresh@ */
|
||||
pv_state_set_format(state, opts->progress, opts->timer, can_have_eta ? opts->eta : false,
|
||||
can_have_eta ? opts->fineta : false, opts->rate, opts->average_rate,
|
||||
opts->bytes, opts->bufpercent, opts->lastwritten, _("(input)"));
|
||||
/*@+mustfreefresh@ *//* see below about gettext _() calls. */
|
||||
|
||||
/* Run the main loop as normal. */
|
||||
debug("%s", "running store-and-forward receiver");
|
||||
retcode = pv_main_loop(state);
|
||||
if (0 != retcode)
|
||||
goto end_store_and_forward;
|
||||
|
||||
/* Set the output file back to what it originally was. */
|
||||
debug("%s: %s", "setting output to original value", NULL == opts->output ? "(null)" : opts->output);
|
||||
retcode = pv__set_output(state, opts, opts->output);
|
||||
if (0 != retcode)
|
||||
goto end_store_and_forward;
|
||||
|
||||
/* Replace the list of input files with the store-and-forward file. */
|
||||
debug("%s", "resetting input file list");
|
||||
pv_state_inputfiles(state, 1, (const char **) &real_store_and_forward_file);
|
||||
|
||||
/* Recalculate the input size. */
|
||||
pv_state_size_set(state, pv_calc_total_size(state));
|
||||
|
||||
/* Reset the format, since we might have been asked to show ETA. */
|
||||
pv_state_set_format(state, opts->progress, opts->timer, opts->eta,
|
||||
opts->fineta, opts->rate, opts->average_rate,
|
||||
opts->bytes, opts->bufpercent, opts->lastwritten, opts->name);
|
||||
|
||||
/* Reset calculated values in the state. */
|
||||
pv_state_reset(state);
|
||||
|
||||
/* Run the main loop again. */
|
||||
debug("%s", "running store-and-forward transmitter");
|
||||
retcode = pv_main_loop(state);
|
||||
|
||||
end_store_and_forward:
|
||||
if (use_temporary_file)
|
||||
(void) remove(tmp_filename);
|
||||
|
||||
return retcode;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Process command-line arguments and set option flags, then call functions
|
||||
@@ -38,6 +278,11 @@ int main(int argc, char **argv)
|
||||
/*@only@ */ opts_t opts = NULL;
|
||||
/*@only@ */ pvstate_t state = NULL;
|
||||
int retcode = 0;
|
||||
bool can_have_eta = true;
|
||||
|
||||
#if ! HAVE_SETPROCTITLE
|
||||
initproctitle(argc, argv);
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_NLS
|
||||
/* Initialise language translation. */
|
||||
@@ -49,8 +294,8 @@ int main(int argc, char **argv)
|
||||
/* Parse the command line arguments. */
|
||||
opts = opts_parse(argc >= 0 ? (unsigned int) argc : 0, argv);
|
||||
if (NULL == opts) {
|
||||
debug("%s: %d", "exiting with status", 64);
|
||||
return 64;
|
||||
debug("%s: %d", "exiting with status", PV_ERROREXIT_MEMORY);
|
||||
return PV_ERROREXIT_MEMORY;
|
||||
}
|
||||
|
||||
/* Early exit if necessary, such as with "-h". */
|
||||
@@ -73,8 +318,8 @@ int main(int argc, char **argv)
|
||||
*/
|
||||
fprintf(stderr, "%s: %s: %s\n", opts->program_name, _("state allocation failed"), strerror(errno));
|
||||
opts_free(opts);
|
||||
debug("%s: %d", "exiting with status", 64);
|
||||
return 64;
|
||||
debug("%s: %d", "exiting with status", PV_ERROREXIT_MEMORY);
|
||||
return PV_ERROREXIT_MEMORY;
|
||||
/*@+mustfreefresh@ */
|
||||
}
|
||||
|
||||
@@ -99,80 +344,13 @@ int main(int argc, char **argv)
|
||||
* Write a PID file if -P was specified.
|
||||
*/
|
||||
if (opts->pidfile != NULL) {
|
||||
char *pidfile_tmp_name;
|
||||
size_t pidfile_tmp_bufsize;
|
||||
int pidfile_tmp_fd;
|
||||
FILE *pidfile_tmp_fptr;
|
||||
mode_t prev_umask;
|
||||
|
||||
pidfile_tmp_bufsize = 16 + strlen(opts->pidfile); /* flawfinder: ignore */
|
||||
/*
|
||||
* flawfinder rationale: pidfile was supplied as an argument
|
||||
* so we have to assume it is \0 terminated.
|
||||
*/
|
||||
pidfile_tmp_name = malloc(pidfile_tmp_bufsize);
|
||||
if (NULL == pidfile_tmp_name) {
|
||||
fprintf(stderr, "%s: %s\n", opts->program_name, strerror(errno));
|
||||
int pidfile_rc;
|
||||
pidfile_rc = pv__write_pidfile(opts);
|
||||
if (0 != pidfile_rc) {
|
||||
pv_state_free(state);
|
||||
opts_free(opts);
|
||||
return 1;
|
||||
return pidfile_rc;
|
||||
}
|
||||
memset(pidfile_tmp_name, 0, pidfile_tmp_bufsize);
|
||||
(void) pv_snprintf(pidfile_tmp_name, pidfile_tmp_bufsize, "%s.XXXXXX", opts->pidfile);
|
||||
|
||||
/*@-type@ *//* splint doesn't like mode_t */
|
||||
prev_umask = umask(0000); /* flawfinder: ignore */
|
||||
(void) umask(prev_umask | 0133); /* flawfinder: ignore */
|
||||
|
||||
/*@-unrecog@ *//* splint doesn't know mkstemp() */
|
||||
pidfile_tmp_fd = mkstemp(pidfile_tmp_name); /* flawfinder: ignore */
|
||||
/*@+unrecog@ */
|
||||
if (pidfile_tmp_fd < 0) {
|
||||
fprintf(stderr, "%s: %s: %s\n", opts->program_name, pidfile_tmp_name, strerror(errno));
|
||||
(void) umask(prev_umask); /* flawfinder: ignore */
|
||||
free(pidfile_tmp_name);
|
||||
pv_state_free(state);
|
||||
opts_free(opts);
|
||||
return 1;
|
||||
}
|
||||
|
||||
(void) umask(prev_umask); /* flawfinder: ignore */
|
||||
|
||||
/*
|
||||
* flawfinder rationale (umask, mkstemp) - flawfinder
|
||||
* recommends setting the most restrictive umask possible
|
||||
* when calling mkstemp(), so this is what we have done.
|
||||
*
|
||||
* We get the original umask and OR it with 0133 to make
|
||||
* sure new files will be at least chmod 644. Then we put
|
||||
* the umask back to what it was, after creating the
|
||||
* temporary file.
|
||||
*/
|
||||
|
||||
/*@+type@ */
|
||||
|
||||
pidfile_tmp_fptr = fdopen(pidfile_tmp_fd, "w");
|
||||
if (NULL == pidfile_tmp_fptr) {
|
||||
fprintf(stderr, "%s: %s: %s\n", opts->program_name, pidfile_tmp_name, strerror(errno));
|
||||
(void) close(pidfile_tmp_fd);
|
||||
(void) remove(pidfile_tmp_name);
|
||||
free(pidfile_tmp_name);
|
||||
pv_state_free(state);
|
||||
opts_free(opts);
|
||||
return 1;
|
||||
}
|
||||
|
||||
fprintf(pidfile_tmp_fptr, "%d\n", getpid());
|
||||
if (0 != fclose(pidfile_tmp_fptr)) {
|
||||
fprintf(stderr, "%s: %s: %s\n", opts->program_name, opts->pidfile, strerror(errno));
|
||||
}
|
||||
|
||||
if (rename(pidfile_tmp_name, opts->pidfile) < 0) {
|
||||
fprintf(stderr, "%s: %s: %s\n", opts->program_name, opts->pidfile, strerror(errno));
|
||||
(void) remove(pidfile_tmp_name);
|
||||
}
|
||||
|
||||
free(pidfile_tmp_name);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -183,7 +361,7 @@ int main(int argc, char **argv)
|
||||
if (!opts_add_file(opts, "-")) {
|
||||
pv_state_free(state);
|
||||
opts_free(opts);
|
||||
return 64;
|
||||
return PV_ERROREXIT_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,27 +372,6 @@ int main(int argc, char **argv)
|
||||
pv_state_inputfiles(state, opts->argc, (const char **) (opts->argv));
|
||||
}
|
||||
|
||||
/* Total size calculation, in normal transfer mode. */
|
||||
if (0 == opts->watch_pid) {
|
||||
/*
|
||||
* If no size was given, try to calculate the total size.
|
||||
*/
|
||||
if (0 == opts->size) {
|
||||
pv_state_linemode_set(state, opts->linemode);
|
||||
pv_state_null_terminated_lines_set(state, opts->null_terminated_lines);
|
||||
opts->size = pv_calc_total_size(state);
|
||||
debug("%s: %llu", "no size given - calculated", opts->size);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the size is unknown, we cannot have an ETA.
|
||||
*/
|
||||
if (opts->size < 1) {
|
||||
opts->eta = false;
|
||||
debug("%s", "size unknown - ETA disabled");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If stderr is not a terminal and we're neither forcing output nor
|
||||
* outputting numerically, we will have nothing to display at all.
|
||||
@@ -265,23 +422,69 @@ int main(int argc, char **argv)
|
||||
opts->interval = 600;
|
||||
|
||||
/*
|
||||
* Copy parameters from options into main state.
|
||||
* Set output file, treating no output or "-" as stdout; we have to
|
||||
* do this before looking at setting the size, as the size
|
||||
* calculation looks at the output file if the input size can't be
|
||||
* calculated (issue #91).
|
||||
*/
|
||||
retcode = pv__set_output(state, opts, opts->output);
|
||||
if (0 != retcode) {
|
||||
pv_state_free(state);
|
||||
opts_free(opts);
|
||||
return retcode;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy the "stop at size" option before checking the total size,
|
||||
* since calculating the size from the output block device size
|
||||
* after this may want to force this setting on, and if we set it
|
||||
* afterwards, we undo the override.
|
||||
*/
|
||||
pv_state_stop_at_size_set(state, opts->stop_at_size);
|
||||
|
||||
/* Total size calculation, in normal transfer mode. */
|
||||
if (0 == opts->watch_pid) {
|
||||
/*
|
||||
* If no size was given, try to calculate the total size.
|
||||
*/
|
||||
if (0 == opts->size) {
|
||||
pv_state_linemode_set(state, opts->linemode);
|
||||
pv_state_null_terminated_lines_set(state, opts->null_terminated_lines);
|
||||
opts->size = pv_calc_total_size(state);
|
||||
debug("%s: %llu", "no size given - calculated", opts->size);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the size is unknown, we cannot have an ETA.
|
||||
*/
|
||||
if (opts->size < 1) {
|
||||
can_have_eta = false;
|
||||
debug("%s", "size unknown - ETA disabled");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy the remaining parameters from the options into the main
|
||||
* state.
|
||||
*/
|
||||
|
||||
pv_state_interval_set(state, opts->interval);
|
||||
pv_state_width_set(state, opts->width, opts->width_set_manually);
|
||||
pv_state_height_set(state, opts->height, opts->height_set_manually);
|
||||
pv_state_no_display_set(state, opts->no_display);
|
||||
pv_state_force_set(state, opts->force);
|
||||
pv_state_cursor_set(state, opts->cursor);
|
||||
pv_state_show_stats_set(state, opts->show_stats);
|
||||
pv_state_numeric_set(state, opts->numeric);
|
||||
pv_state_wait_set(state, opts->wait);
|
||||
pv_state_delay_start_set(state, opts->delay_start);
|
||||
pv_state_rate_gauge_set(state, opts->rate_gauge);
|
||||
pv_state_linemode_set(state, opts->linemode);
|
||||
pv_state_bits_set(state, opts->bits);
|
||||
pv_state_decimal_units_set(state, opts->decimal_units);
|
||||
pv_state_null_terminated_lines_set(state, opts->null_terminated_lines);
|
||||
pv_state_skip_errors_set(state, opts->skip_errors);
|
||||
pv_state_error_skip_block_set(state, opts->error_skip_block);
|
||||
pv_state_stop_at_size_set(state, opts->stop_at_size);
|
||||
pv_state_sync_after_write_set(state, opts->sync_after_write);
|
||||
pv_state_direct_io_set(state, opts->direct_io);
|
||||
pv_state_discard_input_set(state, opts->discard_input);
|
||||
@@ -291,33 +494,29 @@ int main(int argc, char **argv)
|
||||
pv_state_size_set(state, opts->size);
|
||||
pv_state_name_set(state, opts->name);
|
||||
pv_state_format_string_set(state, opts->format);
|
||||
pv_state_extra_display_set(state, opts->extra_display);
|
||||
pv_state_watch_pid_set(state, opts->watch_pid);
|
||||
pv_state_watch_fd_set(state, opts->watch_fd);
|
||||
pv_state_average_rate_window_set(state, opts->average_rate_window);
|
||||
|
||||
pv_state_set_format(state, opts->progress, opts->timer, opts->eta,
|
||||
opts->fineta, opts->rate, opts->average_rate,
|
||||
pv_state_set_format(state, opts->progress, opts->timer, can_have_eta ? opts->eta : false,
|
||||
can_have_eta ? opts->fineta : false, opts->rate, opts->average_rate,
|
||||
opts->bytes, opts->bufpercent, opts->lastwritten, opts->name);
|
||||
|
||||
#ifdef MAKE_STDOUT_NONBLOCKING
|
||||
/*
|
||||
* Try and make standard output use non-blocking I/O.
|
||||
*
|
||||
* Note that this can cause problems with (broken) applications
|
||||
* such as dd.
|
||||
*/
|
||||
fcntl(STDOUT_FILENO, F_SETFL, O_NONBLOCK | fcntl(STDOUT_FILENO, F_GETFL));
|
||||
#endif /* MAKE_STDOUT_NONBLOCKING */
|
||||
|
||||
/* Initialise the signal handling. */
|
||||
pv_sig_init(state);
|
||||
|
||||
/* Run the appropriate main loop. */
|
||||
if (0 == opts->watch_pid) {
|
||||
if (0 == opts->watch_pid && NULL == opts->store_and_forward_file) {
|
||||
/* Normal "transfer data" mode. */
|
||||
pv_remote_init();
|
||||
retcode = pv_main_loop(state);
|
||||
pv_remote_fini();
|
||||
} else if (0 == opts->watch_pid && NULL != opts->store_and_forward_file) {
|
||||
/* Store-and-forward transfer mode. */
|
||||
pv_remote_init();
|
||||
retcode = pv__store_and_forward(state, opts, can_have_eta);
|
||||
pv_remote_fini();
|
||||
} else if (0 != opts->watch_pid && -1 == opts->watch_fd) {
|
||||
/* "Watch all file descriptors of another process" mode. */
|
||||
retcode = pv_watchpid_loop(state);
|
||||
@@ -346,5 +545,3 @@ int main(int argc, char **argv)
|
||||
|
||||
return retcode;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
||||
+220
-30
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Parse command-line options.
|
||||
*
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2024 Andrew Wood
|
||||
*
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
@@ -15,6 +15,17 @@
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#ifdef HAVE_SYS_SYSMACROS_H
|
||||
#include <sys/sysmacros.h>
|
||||
#ifdef major
|
||||
#ifdef minor
|
||||
#ifdef HAVE_STRUCT_STAT_ST_RDEV
|
||||
#define CAN_BUILD_SYSFS_FILENAME 1
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#ifdef HAVE_GETOPT_H
|
||||
#include <getopt.h>
|
||||
@@ -44,6 +55,12 @@ void opts_free( /*@only@ */ opts_t opts)
|
||||
free(opts->format);
|
||||
if (NULL != opts->pidfile)
|
||||
free(opts->pidfile);
|
||||
if (NULL != opts->output)
|
||||
free(opts->output);
|
||||
if (NULL != opts->store_and_forward_file)
|
||||
free(opts->store_and_forward_file);
|
||||
if (NULL != opts->extra_display)
|
||||
free(opts->extra_display);
|
||||
if (NULL != opts->argv)
|
||||
free(opts->argv);
|
||||
/*@+keeptrans@ */
|
||||
@@ -86,6 +103,154 @@ bool opts_add_file(opts_t opts, const char *filename)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set opts->size from the size of the file whose name is size_file,
|
||||
* returning false (and reporting the error) if there is a problem.
|
||||
*
|
||||
* If size_file points to a block device, the size of the block device is
|
||||
* used.
|
||||
*/
|
||||
static bool opts_use_size_of_file(opts_t opts, const char *size_file)
|
||||
{
|
||||
struct stat sb;
|
||||
int stat_rc;
|
||||
#ifdef CAN_BUILD_SYSFS_FILENAME
|
||||
char sysfs_filename[512]; /* flawfinder: ignore */
|
||||
FILE *sysfs_fptr;
|
||||
long long sysfs_size;
|
||||
#endif /* CAN_BUILD_SYSFS_FILENAME */
|
||||
int device_fd;
|
||||
off_t device_size;
|
||||
|
||||
/*
|
||||
* flawfinder rationale: sysfs_filename is only used with
|
||||
* pv_snprintf() which guarantees it will be bounded and zero
|
||||
* terminated.
|
||||
*/
|
||||
|
||||
stat_rc = 0;
|
||||
memset(&sb, 0, sizeof(sb));
|
||||
|
||||
stat_rc = stat(size_file, &sb);
|
||||
|
||||
if (0 != stat_rc) {
|
||||
/*@-mustfreefresh@ */
|
||||
/*
|
||||
* splint note: the gettext calls made by _() cause memory
|
||||
* leak warnings, but in this case it's unavoidable, and
|
||||
* mitigated by the fact we only translate each string once.
|
||||
*/
|
||||
fprintf(stderr, "%s: %s: %s: %s\n",
|
||||
opts->program_name, size_file, _("failed to stat file"), strerror(errno));
|
||||
return false;
|
||||
/*@+mustfreefresh@ */
|
||||
}
|
||||
|
||||
/* This was a regular file - use its size and return. */
|
||||
if (S_ISREG((mode_t) (sb.st_mode))) {
|
||||
opts->size = (off_t) (sb.st_size);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* This was a directory - report an error. */
|
||||
if (S_ISDIR((mode_t) (sb.st_mode))) {
|
||||
/*@-mustfreefresh@ *//* see above */
|
||||
fprintf(stderr, "%s: %s: %s\n", opts->program_name, size_file, _("is a directory"));
|
||||
return false;
|
||||
/*@+mustfreefresh@ */
|
||||
}
|
||||
|
||||
/* This was not a block device - just use the size and return. */
|
||||
if (!S_ISBLK((mode_t) (sb.st_mode))) {
|
||||
opts->size = (off_t) (sb.st_size);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Block device - determine its size by looking for
|
||||
* /sys/dev/block/MAJOR:MINOR/size, and if that fails, try opening
|
||||
* the file and seeking to the end.
|
||||
*/
|
||||
|
||||
#ifdef CAN_BUILD_SYSFS_FILENAME
|
||||
/*
|
||||
* Try the sysfs method - lightest touch and requires no read access
|
||||
* to the actual block device.
|
||||
*/
|
||||
|
||||
memset(sysfs_filename, 0, sizeof(sysfs_filename));
|
||||
if (pv_snprintf
|
||||
(sysfs_filename, sizeof(sysfs_filename), "/sys/dev/block/%u:%u/size", major(sb.st_rdev),
|
||||
minor(sb.st_rdev)) < 0) {
|
||||
/*@-mustfreefresh@ *//* see above */
|
||||
fprintf(stderr, "%s: %s: %s: %s\n",
|
||||
opts->program_name, size_file, _("failed to generate sysfs filename"), strerror(errno));
|
||||
return false;
|
||||
/*@+mustfreefresh@ */
|
||||
}
|
||||
|
||||
sysfs_fptr = fopen(sysfs_filename, "r"); /* flawfinder: ignore */
|
||||
/*
|
||||
* flawfinder rationale: sysfs is trusted here, the filename is
|
||||
* predictable, and we are restricted to reading one number.
|
||||
*/
|
||||
if (NULL != sysfs_fptr) {
|
||||
sysfs_size = -1;
|
||||
if (1 == fscanf(sysfs_fptr, "%lld", &sysfs_size)) {
|
||||
/* Read successful - use the value (* 512) and return. */
|
||||
(void) fclose(sysfs_fptr);
|
||||
opts->size = (off_t) sysfs_size *512;
|
||||
return true;
|
||||
}
|
||||
/* Read not successful - report the error and return. */
|
||||
/* NB we must fclose() after reporting to retain errno. */
|
||||
/*@-mustfreefresh@ *//* see above */
|
||||
fprintf(stderr, "%s: %s: %s: %s\n",
|
||||
opts->program_name, size_file, _("failed to read sysfs size file"), strerror(errno));
|
||||
(void) fclose(sysfs_fptr);
|
||||
return false;
|
||||
/*@+mustfreefresh@ */
|
||||
}
|
||||
#endif /* CAN_BUILD_SYSFS_FILENAME */
|
||||
|
||||
/*
|
||||
* Try opening the block device and seeking to the end.
|
||||
*/
|
||||
device_fd = open(size_file, O_RDONLY); /* flawfinder: ignore */
|
||||
/*
|
||||
* flawfinder rationale: the filename is under the direct control of
|
||||
* the operator by its nature, so we can't refuse to open symlinks
|
||||
* etc as that would be counterintuitive.
|
||||
*/
|
||||
|
||||
if (device_fd < 0) {
|
||||
/*@-mustfreefresh@ *//* see above */
|
||||
fprintf(stderr, "%s: %s: %s: %s\n",
|
||||
opts->program_name, size_file, _("failed to open block device"), strerror(errno));
|
||||
return false;
|
||||
/*@+mustfreefresh@ */
|
||||
}
|
||||
|
||||
device_size = (off_t) lseek(device_fd, 0, SEEK_END);
|
||||
|
||||
if (device_size < 0) {
|
||||
/*@-mustfreefresh@ *//* see above */
|
||||
fprintf(stderr, "%s: %s: %s: %s\n",
|
||||
opts->program_name, size_file, _("failed to determine size of block device"), strerror(errno));
|
||||
/* NB close() after reporting error, to preserve errno. */
|
||||
(void) close(device_fd);
|
||||
return false;
|
||||
/*@+mustfreefresh@ */
|
||||
}
|
||||
|
||||
(void) close(device_fd);
|
||||
|
||||
/* Use the size we found. */
|
||||
opts->size = device_size;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Parse the given command-line arguments into an opts_t object, handling
|
||||
* "help" and "version" options internally.
|
||||
@@ -114,6 +279,7 @@ opts_t opts_parse(unsigned int argc, char **argv)
|
||||
{ "average-rate", 0, NULL, (int) 'a' },
|
||||
{ "bytes", 0, NULL, (int) 'b' },
|
||||
{ "bits", 0, NULL, (int) '8' },
|
||||
{ "si", 0, NULL, (int) 'k' },
|
||||
{ "buffer-percent", 0, NULL, (int) 'T' },
|
||||
{ "last-written", 1, NULL, (int) 'A' },
|
||||
{ "force", 0, NULL, (int) 'f' },
|
||||
@@ -123,6 +289,7 @@ opts_t opts_parse(unsigned int argc, char **argv)
|
||||
{ "wait", 0, NULL, (int) 'W' },
|
||||
{ "delay-start", 1, NULL, (int) 'D' },
|
||||
{ "size", 1, NULL, (int) 's' },
|
||||
{ "gauge", 0, NULL, (int) 'g' },
|
||||
{ "line-mode", 0, NULL, (int) 'l' },
|
||||
{ "null", 0, NULL, (int) '0' },
|
||||
{ "interval", 1, NULL, (int) 'i' },
|
||||
@@ -130,6 +297,8 @@ opts_t opts_parse(unsigned int argc, char **argv)
|
||||
{ "height", 1, NULL, (int) 'H' },
|
||||
{ "name", 1, NULL, (int) 'N' },
|
||||
{ "format", 1, NULL, (int) 'F' },
|
||||
{ "extra-display", 1, NULL, (int) 'x' },
|
||||
{ "stats", 0, NULL, (int) 'v' },
|
||||
{ "rate-limit", 1, NULL, (int) 'L' },
|
||||
{ "buffer-size", 1, NULL, (int) 'B' },
|
||||
{ "no-splice", 0, NULL, (int) 'C' },
|
||||
@@ -139,9 +308,11 @@ opts_t opts_parse(unsigned int argc, char **argv)
|
||||
{ "sync", 0, NULL, (int) 'Y' },
|
||||
{ "direct-io", 0, NULL, (int) 'K' },
|
||||
{ "discard", 0, NULL, (int) 'X' },
|
||||
{ "store-and-forward", 1, NULL, (int) 'U' },
|
||||
{ "remote", 1, NULL, (int) 'R' },
|
||||
{ "pidfile", 1, NULL, (int) 'P' },
|
||||
{ "watchfd", 1, NULL, (int) 'd' },
|
||||
{ "output", 1, NULL, (int) 'o' },
|
||||
{ "average-rate-window", 1, NULL, (int) 'm' },
|
||||
#ifdef ENABLE_DEBUGGING
|
||||
{ "debug", 1, NULL, (int) '!' },
|
||||
@@ -151,7 +322,7 @@ opts_t opts_parse(unsigned int argc, char **argv)
|
||||
/*@+nullassign@ */
|
||||
int option_index = 0;
|
||||
#endif /* HAVE_GETOPT_LONG */
|
||||
char *short_options = "hVpteIrab8TA:fnqcWD:s:l0i:w:H:N:F:L:B:CEZ:SYKXR:P:d:m:"
|
||||
char *short_options = "hVpteIrab8kTA:fvnqcWD:s:gl0i:w:H:N:F:x:L:B:CEZ:SYKXU:R:P:d:m:o:"
|
||||
#ifdef ENABLE_DEBUGGING
|
||||
"!:"
|
||||
#endif
|
||||
@@ -335,19 +506,25 @@ opts_t opts_parse(unsigned int argc, char **argv)
|
||||
opts->bits = true;
|
||||
numopts++;
|
||||
break;
|
||||
case 'k':
|
||||
opts->decimal_units = true;
|
||||
break;
|
||||
case 'T':
|
||||
opts->bufpercent = true;
|
||||
numopts++;
|
||||
opts->no_splice = true;
|
||||
break;
|
||||
case 'A':
|
||||
opts->lastwritten = (size_t) pv_getnum_count(optarg);
|
||||
opts->lastwritten = (size_t) pv_getnum_count(optarg, opts->decimal_units);
|
||||
numopts++;
|
||||
opts->no_splice = true;
|
||||
break;
|
||||
case 'f':
|
||||
opts->force = true;
|
||||
break;
|
||||
case 'v':
|
||||
opts->show_stats = true;
|
||||
break;
|
||||
case 'n':
|
||||
opts->numeric = true;
|
||||
numopts++;
|
||||
@@ -366,30 +543,21 @@ opts_t opts_parse(unsigned int argc, char **argv)
|
||||
opts->delay_start = pv_getnum_interval(optarg);
|
||||
break;
|
||||
case 's':
|
||||
/* Permit "@<filename>" as well as just a number. */
|
||||
if ('@' == *optarg) {
|
||||
if ('@' != *optarg) {
|
||||
/* A number was passed, not "@<filename>". */
|
||||
opts->size = pv_getnum_size(optarg, opts->decimal_units);
|
||||
} else {
|
||||
/* Permit "@<filename>". */
|
||||
const char *size_file = 1 + optarg;
|
||||
struct stat sb;
|
||||
int rc;
|
||||
|
||||
rc = 0;
|
||||
memset(&sb, 0, sizeof(sb));
|
||||
rc = stat(size_file, &sb);
|
||||
if (0 == rc) {
|
||||
opts->size = (off_t) (sb.st_size);
|
||||
} else {
|
||||
/*@-mustfreefresh@ *//* see above */
|
||||
fprintf(stderr, "%s: %s %s: %s\n",
|
||||
opts->program_name,
|
||||
_("failed to stat file"), size_file, strerror(errno));
|
||||
if (!opts_use_size_of_file(opts, size_file)) {
|
||||
opts_free(opts);
|
||||
return NULL;
|
||||
/*@+mustfreefresh@ */
|
||||
}
|
||||
} else {
|
||||
opts->size = pv_getnum_size(optarg);
|
||||
}
|
||||
break;
|
||||
case 'g':
|
||||
opts->rate_gauge = true;
|
||||
break;
|
||||
case 'l':
|
||||
opts->linemode = true;
|
||||
break;
|
||||
@@ -401,11 +569,11 @@ opts_t opts_parse(unsigned int argc, char **argv)
|
||||
opts->interval = pv_getnum_interval(optarg);
|
||||
break;
|
||||
case 'w':
|
||||
opts->width = pv_getnum_count(optarg);
|
||||
opts->width = pv_getnum_count(optarg, opts->decimal_units);
|
||||
opts->width_set_manually = opts->width == 0 ? false : true;
|
||||
break;
|
||||
case 'H':
|
||||
opts->height = pv_getnum_count(optarg);
|
||||
opts->height = pv_getnum_count(optarg, opts->decimal_units);
|
||||
opts->height_set_manually = opts->height == 0 ? false : true;
|
||||
break;
|
||||
case 'N':
|
||||
@@ -417,10 +585,10 @@ opts_t opts_parse(unsigned int argc, char **argv)
|
||||
}
|
||||
break;
|
||||
case 'L':
|
||||
opts->rate_limit = pv_getnum_size(optarg);
|
||||
opts->rate_limit = pv_getnum_size(optarg, opts->decimal_units);
|
||||
break;
|
||||
case 'B':
|
||||
opts->buffer_size = (size_t) pv_getnum_size(optarg);
|
||||
opts->buffer_size = (size_t) pv_getnum_size(optarg, opts->decimal_units);
|
||||
opts->no_splice = true;
|
||||
break;
|
||||
case 'C':
|
||||
@@ -430,7 +598,7 @@ opts_t opts_parse(unsigned int argc, char **argv)
|
||||
opts->skip_errors++;
|
||||
break;
|
||||
case 'Z':
|
||||
opts->error_skip_block = pv_getnum_size(optarg);
|
||||
opts->error_skip_block = pv_getnum_size(optarg, opts->decimal_units);
|
||||
break;
|
||||
case 'S':
|
||||
opts->stop_at_size = true;
|
||||
@@ -445,8 +613,16 @@ opts_t opts_parse(unsigned int argc, char **argv)
|
||||
opts->discard_input = true;
|
||||
opts->no_splice = true;
|
||||
break;
|
||||
case 'U':
|
||||
opts->store_and_forward_file = pv_strdup(optarg);
|
||||
if (NULL == opts->store_and_forward_file) {
|
||||
fprintf(stderr, "%s: -U: %s\n", opts->program_name, strerror(errno));
|
||||
opts_free(opts);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case 'R':
|
||||
opts->remote = pv_getnum_count(optarg);
|
||||
opts->remote = (pid_t) pv_getnum_count(optarg, false);
|
||||
break;
|
||||
case 'P':
|
||||
opts->pidfile = pv_strdup(optarg);
|
||||
@@ -464,6 +640,14 @@ opts_t opts_parse(unsigned int argc, char **argv)
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case 'x':
|
||||
opts->extra_display = pv_strdup(optarg);
|
||||
if (NULL == opts->extra_display) {
|
||||
fprintf(stderr, "%s: -x: %s\n", opts->program_name, strerror(errno));
|
||||
opts_free(opts);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case 'd':
|
||||
parse_pid = 0;
|
||||
parse_fd = -1;
|
||||
@@ -472,8 +656,16 @@ opts_t opts_parse(unsigned int argc, char **argv)
|
||||
opts->watch_pid = (pid_t) parse_pid;
|
||||
opts->watch_fd = parse_fd;
|
||||
break;
|
||||
case 'o':
|
||||
opts->output = pv_strdup(optarg);
|
||||
if (NULL == opts->output) {
|
||||
fprintf(stderr, "%s: -o: %s\n", opts->program_name, strerror(errno));
|
||||
opts_free(opts);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case 'm':
|
||||
opts->average_rate_window = pv_getnum_count(optarg);
|
||||
opts->average_rate_window = pv_getnum_count(optarg, opts->decimal_units);
|
||||
break;
|
||||
#ifdef ENABLE_DEBUGGING
|
||||
case '!':
|
||||
@@ -594,5 +786,3 @@ opts_t opts_parse(unsigned int argc, char **argv)
|
||||
|
||||
return opts;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
||||
+23
-16
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Remote-control functions.
|
||||
*
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2024 Andrew Wood
|
||||
*
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
@@ -21,7 +21,7 @@
|
||||
#include <sys/time.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifdef SA_SIGINFO
|
||||
#ifdef SIGINFO_PROVIDES_PID
|
||||
void pv_error(pvstate_t, char *, ...);
|
||||
|
||||
struct remote_msg {
|
||||
@@ -57,10 +57,12 @@ struct remote_msg {
|
||||
* file associated with a particular process ID; it will be opened for
|
||||
* writing if "sender" is true. Returns NULL on error.
|
||||
*/
|
||||
/*@null@ */
|
||||
/*@dependent@ */
|
||||
static FILE *pv__control_file(char *filename, size_t bufsize, pid_t control_pid, bool sender)
|
||||
{
|
||||
int open_flags, open_mode, control_fd;
|
||||
FILE *control_fptr;
|
||||
/*@dependent@ */ FILE *control_fptr = NULL;
|
||||
|
||||
open_flags = O_RDONLY;
|
||||
#ifdef O_NOFOLLOW
|
||||
@@ -84,6 +86,13 @@ static FILE *pv__control_file(char *filename, size_t bufsize, pid_t control_pid,
|
||||
home_dir = getenv("HOME"); /* flawfinder: ignore */
|
||||
if (NULL == home_dir)
|
||||
return NULL;
|
||||
if ('\0' == home_dir[0])
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* flawfinder rationale: null and zero-size values are
|
||||
* rejected, and the destination buffer is bounded.
|
||||
*/
|
||||
|
||||
(void) pv_snprintf(filename, bufsize, "%s/.pv/remote.%lu", home_dir, (unsigned long) control_pid);
|
||||
control_fd = open(filename, open_flags, open_mode); /* flawfinder: ignore */
|
||||
@@ -151,7 +160,7 @@ int pv_remote_set(opts_t opts, pvstate_t state)
|
||||
*/
|
||||
if (kill((pid_t) (opts->remote), 0) != 0) {
|
||||
pv_error(state, "%u: %s", opts->remote, strerror(errno));
|
||||
return 1;
|
||||
return PV_ERROREXIT_REMOTE_OR_PID;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -209,10 +218,10 @@ int pv_remote_set(opts_t opts, pvstate_t state)
|
||||
* Get the filename and file stream to use for remote control.
|
||||
*/
|
||||
memset(control_filename, 0, sizeof(control_filename));
|
||||
control_fptr = pv__control_file(control_filename, sizeof(control_filename), getpid(), true);
|
||||
control_fptr = pv__control_file(control_filename, sizeof(control_filename), (pid_t) getpid(), true);
|
||||
if (NULL == control_fptr) {
|
||||
pv_error(state, "%s", strerror(errno));
|
||||
return 1;
|
||||
return PV_ERROREXIT_REMOTE_OR_PID;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -223,13 +232,13 @@ int pv_remote_set(opts_t opts, pvstate_t state)
|
||||
pv_error(state, "%s", strerror(errno));
|
||||
(void) fclose(control_fptr);
|
||||
(void) remove(control_filename);
|
||||
return 1;
|
||||
return PV_ERROREXIT_REMOTE_OR_PID;
|
||||
}
|
||||
|
||||
if (0 != fclose(control_fptr)) {
|
||||
pv_error(state, "%s", strerror(errno));
|
||||
(void) remove(control_filename);
|
||||
return 1;
|
||||
return PV_ERROREXIT_REMOTE_OR_PID;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -241,7 +250,7 @@ int pv_remote_set(opts_t opts, pvstate_t state)
|
||||
if (kill((pid_t) (opts->remote), SIGUSR2) != 0) {
|
||||
pv_error(state, "%u: %s", opts->remote, strerror(errno));
|
||||
(void) remove(control_filename);
|
||||
return 1;
|
||||
return PV_ERROREXIT_REMOTE_OR_PID;
|
||||
}
|
||||
|
||||
debug("%s", "message sent");
|
||||
@@ -293,7 +302,7 @@ int pv_remote_set(opts_t opts, pvstate_t state)
|
||||
* fact we only translate each string once.
|
||||
*/
|
||||
pv_error(state, "%u: %s", opts->remote, _("message not received"));
|
||||
return 1;
|
||||
return PV_ERROREXIT_REMOTE_OR_PID;
|
||||
/*@+mustfreefresh @ */
|
||||
}
|
||||
|
||||
@@ -324,7 +333,7 @@ void pv_remote_check(pvstate_t state)
|
||||
memset(control_filename, 0, sizeof(control_filename));
|
||||
control_fptr = pv__control_file(control_filename, sizeof(control_filename), signal_sender, false);
|
||||
if (NULL == control_fptr) {
|
||||
pv_error(state, "%s", strerror(errno));
|
||||
pv_error(state, "%s: %s", control_filename, strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -398,10 +407,10 @@ void pv_remote_fini(void)
|
||||
{
|
||||
}
|
||||
|
||||
#else /* !SA_SIGINFO */
|
||||
#else /* !SIGINFO_PROVIDES_PID */
|
||||
|
||||
/*
|
||||
* Dummy stubs for remote control when we don't have SA_SIGINFO.
|
||||
* Dummy stubs for remote control when we don't have SIGINFO_PROVIDES_PID.
|
||||
*/
|
||||
void pv_remote_init(void)
|
||||
{
|
||||
@@ -421,9 +430,7 @@ int pv_remote_set( /*@unused@ */
|
||||
/*@-mustfreefresh@ *//* splint - see above */
|
||||
fprintf(stderr, "%s\n", _("SA_SIGINFO not supported on this system"));
|
||||
/*@+mustfreefresh@ */
|
||||
return 1;
|
||||
return PV_ERROREXIT_REMOTE_OR_PID;
|
||||
}
|
||||
|
||||
#endif /* SA_SIGINFO */
|
||||
|
||||
/* EOF */
|
||||
|
||||
+2
-4
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Output version information to stdout.
|
||||
*
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2024 Andrew Wood
|
||||
*
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
@@ -23,7 +23,7 @@ void display_version(void)
|
||||
/* GNU standard first line format: program and version only */
|
||||
printf("%s %s\n", PACKAGE_NAME, PACKAGE_VERSION);
|
||||
/* GNU standard second line format - "Copyright" always in English */
|
||||
printf("Copyright %s %s\n", "2023", "Andrew Wood");
|
||||
printf("Copyright %s %s\n", "2024", "Andrew Wood");
|
||||
/* GNU standard license line and free software notice */
|
||||
printf("%s\n", _("License: GPLv3+ <https://www.gnu.org/licenses/gpl-3.0.html>"));
|
||||
printf("%s\n", _("This is free software: you are free to change and redistribute it."));
|
||||
@@ -31,5 +31,3 @@ void display_version(void)
|
||||
/* Project web site link */
|
||||
printf("\n%s: <%s>\n", _("Project web site"), PACKAGE_URL);
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
||||
+171
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Functions for updating the calculated state of the transfer.
|
||||
*
|
||||
* Copyright 2024 Andrew Wood
|
||||
*
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "pv.h"
|
||||
#include "pv-internal.h"
|
||||
|
||||
|
||||
/*
|
||||
* Update the current average rate, using a ring buffer of past transfer
|
||||
* positions - if this is the first entry, use the provided instantaneous
|
||||
* rate, otherwise calulate the average rate from the difference between the
|
||||
* current position + elapsed time pair, and the oldest pair in the buffer.
|
||||
*/
|
||||
static void pv__update_average_rate_history(pvstate_t state, long double rate)
|
||||
{
|
||||
size_t first = state->calc.history_first;
|
||||
size_t last = state->calc.history_last;
|
||||
long double last_elapsed;
|
||||
|
||||
if (NULL == state->calc.history)
|
||||
return;
|
||||
|
||||
last_elapsed = state->calc.history[last].elapsed_sec;
|
||||
|
||||
/*
|
||||
* Do nothing if this is not the first call but not enough time has
|
||||
* elapsed since the previous call yet.
|
||||
*/
|
||||
if ((last_elapsed > 0.0)
|
||||
&& (state->transfer.elapsed_seconds < (last_elapsed + state->control.history_interval)))
|
||||
return;
|
||||
|
||||
/*
|
||||
* If this is not the first call, add a new entry to the circular
|
||||
* buffer.
|
||||
*/
|
||||
if (last_elapsed > 0.0) {
|
||||
size_t len = state->calc.history_len;
|
||||
last = (last + 1) % len;
|
||||
state->calc.history_last = last;
|
||||
if (last == first) {
|
||||
first = (first + 1) % len;
|
||||
state->calc.history_first = first;
|
||||
}
|
||||
}
|
||||
|
||||
state->calc.history[last].elapsed_sec = state->transfer.elapsed_seconds;
|
||||
state->calc.history[last].transferred = state->transfer.transferred;
|
||||
|
||||
if (first == last) {
|
||||
state->calc.current_avg_rate = rate;
|
||||
} else {
|
||||
off_t bytes = (state->calc.history[last].transferred - state->calc.history[first].transferred);
|
||||
long double sec = (state->calc.history[last].elapsed_sec - state->calc.history[first].elapsed_sec);
|
||||
state->calc.current_avg_rate = (long double) bytes / sec;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Update all calculated transfer state (state->calc).
|
||||
*
|
||||
* If "final" is true, this is the final update, so
|
||||
* state->calc.transfer_rate and state->calc.average_rate are given as an
|
||||
* average over the whole transfer; otherwise they are the current transfer
|
||||
* rate and current average rate.
|
||||
*
|
||||
* The value of state->calc.percentage will reflect the percentage
|
||||
* completion if state->control.size is greater than zero, otherwise it will
|
||||
* increase by 2 each call and wrap at 200.
|
||||
*/
|
||||
void pv_calculate_transfer_rate(pvstate_t state, bool final)
|
||||
{
|
||||
off_t bytes_since_last;
|
||||
long double time_since_last, transfer_rate, average_rate;
|
||||
|
||||
/* Quick safety check - state must exist. */
|
||||
if (NULL == state)
|
||||
return;
|
||||
|
||||
bytes_since_last = 0;
|
||||
if (state->transfer.transferred >= 0) {
|
||||
bytes_since_last = state->transfer.transferred - state->calc.prev_transferred;
|
||||
state->calc.prev_transferred = state->transfer.transferred;
|
||||
}
|
||||
|
||||
/*
|
||||
* In case the time since the last update is very small, we keep
|
||||
* track of amount transferred since the last update, and just keep
|
||||
* adding to that until a reasonable amount of time has passed to
|
||||
* avoid rate spikes or division by zero.
|
||||
*/
|
||||
time_since_last = state->transfer.elapsed_seconds - state->calc.prev_elapsed_sec;
|
||||
if (time_since_last <= 0.01) {
|
||||
transfer_rate = state->calc.prev_rate;
|
||||
state->calc.prev_trans += bytes_since_last;
|
||||
} else {
|
||||
long double measured_rate;
|
||||
|
||||
transfer_rate = ((long double) bytes_since_last + state->calc.prev_trans) / time_since_last;
|
||||
measured_rate = transfer_rate;
|
||||
|
||||
state->calc.prev_elapsed_sec = state->transfer.elapsed_seconds;
|
||||
state->calc.prev_trans = 0;
|
||||
|
||||
if (state->control.bits)
|
||||
measured_rate = 8.0 * measured_rate;
|
||||
|
||||
if ((state->calc.measurements_taken < 1) || (measured_rate < state->calc.rate_min)) {
|
||||
state->calc.rate_min = measured_rate;
|
||||
}
|
||||
if (measured_rate > state->calc.rate_max) {
|
||||
state->calc.rate_max = measured_rate;
|
||||
}
|
||||
state->calc.rate_sum += measured_rate;
|
||||
state->calc.ratesquared_sum += (measured_rate * measured_rate);
|
||||
state->calc.measurements_taken++;
|
||||
}
|
||||
state->calc.prev_rate = transfer_rate;
|
||||
|
||||
/* Update history and current average rate for ETA. */
|
||||
pv__update_average_rate_history(state, transfer_rate);
|
||||
average_rate = state->calc.current_avg_rate;
|
||||
|
||||
/*
|
||||
* If this is the final update at the end of the transfer, we
|
||||
* recalculate the rate - and the average rate - across the whole
|
||||
* period of the transfer.
|
||||
*/
|
||||
if (final) {
|
||||
/* Safety check to avoid division by zero. */
|
||||
if (state->transfer.elapsed_seconds < 0.000001)
|
||||
state->transfer.elapsed_seconds = 0.000001;
|
||||
average_rate =
|
||||
(((long double) (state->transfer.transferred)) -
|
||||
((long double) state->display.initial_offset)) / (long double) (state->transfer.elapsed_seconds);
|
||||
transfer_rate = average_rate;
|
||||
}
|
||||
|
||||
state->calc.transfer_rate = transfer_rate;
|
||||
state->calc.average_rate = average_rate;
|
||||
|
||||
if (state->control.size <= 0) {
|
||||
/*
|
||||
* If we don't know the total size of the incoming data,
|
||||
* then for a percentage, we gradually increase the
|
||||
* percentage completion as data arrives, to a maximum of
|
||||
* 200, then reset it - we use this if we can't calculate
|
||||
* it, so that the numeric percentage output will go
|
||||
* 0%-100%, 100%-0%, 0%-100%, and so on.
|
||||
*/
|
||||
if (transfer_rate > 0)
|
||||
state->calc.percentage += 2;
|
||||
if (state->calc.percentage > 199)
|
||||
state->calc.percentage = 0;
|
||||
} else {
|
||||
state->calc.percentage = pv_percentage(state->transfer.transferred, state->control.size);
|
||||
}
|
||||
|
||||
/* Ensure the percentage is never negative or huge. */
|
||||
if (state->calc.percentage < 0)
|
||||
state->calc.percentage = 0;
|
||||
if (state->calc.percentage > 100000)
|
||||
state->calc.percentage = 100000;
|
||||
}
|
||||
+27
-47
@@ -10,7 +10,7 @@
|
||||
* terminal, so we try to use a lockfile if terminal locking doesn't work,
|
||||
* and finally abort if even that is unavailable.
|
||||
*
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2024 Andrew Wood
|
||||
*
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
@@ -43,32 +43,6 @@
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Write the given buffer to the given file descriptor, retrying until all
|
||||
* bytes have been written or an error has occurred.
|
||||
*/
|
||||
void pv_write_retry(int fd, const char *buf, size_t count)
|
||||
{
|
||||
while (count > 0) {
|
||||
ssize_t nwritten;
|
||||
|
||||
nwritten = write(fd, buf, count);
|
||||
|
||||
if (nwritten < 0) {
|
||||
if ((EINTR == errno) || (EAGAIN == errno)) {
|
||||
continue;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (nwritten < 1)
|
||||
return;
|
||||
|
||||
count -= nwritten;
|
||||
buf += nwritten;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Create a per-euid, per-tty, lockfile in ${TMPDIR:-${TMP:-/tmp}} for the
|
||||
* tty on the given file descriptor.
|
||||
@@ -95,14 +69,16 @@ static void pv_crs_open_lockfile(pvstate_t state, int fd)
|
||||
return;
|
||||
}
|
||||
|
||||
tmpdir = (char *) getenv("TMPDIR"); /* flawfinder: ignore */
|
||||
if ((NULL == tmpdir) || ('\0' == tmpdir[0]))
|
||||
tmpdir = (char *) getenv("TMP"); /* flawfinder: ignore */
|
||||
if ((NULL == tmpdir) || ('\0' == tmpdir[0]))
|
||||
tmpdir = "/tmp";
|
||||
|
||||
/*
|
||||
* We used to look at the TMPDIR or TMP environment variables to
|
||||
* override the temporary directory, but this leads to less
|
||||
* predictable behaviour, and flawfinder points out that relying on
|
||||
* environment variables in this way is not safe. So the lock
|
||||
* directory is hard-coded to "/tmp" now (Sep 2023).
|
||||
* flawfinder rationale: null and zero-size values of $TMPDIR and
|
||||
* $TMP are rejected, and the destination buffer is bounded.
|
||||
*/
|
||||
tmpdir = "/tmp";
|
||||
|
||||
memset(state->cursor.lock_file, 0, PV_SIZEOF_CRS_LOCK_FILE);
|
||||
(void) pv_snprintf(state->cursor.lock_file,
|
||||
@@ -293,7 +269,7 @@ static int pv_crs_get_ypos(int terminalfd)
|
||||
}
|
||||
#endif /* !CURSOR_ANSWERBACK_BYTE_BY_BYTE */
|
||||
|
||||
ypos = (int) pv_getnum_count(cpr + 2);
|
||||
ypos = (int) pv_getnum_count(cpr + 2, false);
|
||||
|
||||
if (0 != tcsetattr(terminalfd, TCSANOW | TCSAFLUSH, &old_tty)) {
|
||||
debug("%s: %s", "tcsetattr (2) failed", strerror(errno));
|
||||
@@ -435,8 +411,8 @@ void pv_crs_init(pvstate_t state)
|
||||
* If we have already set the terminal TOSTOP attribute, set the
|
||||
* flag in shared memory to let the other instances know.
|
||||
*/
|
||||
if ((!state->cursor.noipc) && state->signal.pv_tty_tostop_added && (NULL != state->cursor.shared)) {
|
||||
debug("%s", "propagating local pv_tty_tostop_added true value to shared flag");
|
||||
if ((!state->cursor.noipc) && (1 == state->flag.clear_tty_tostop_on_exit) && (NULL != state->cursor.shared)) {
|
||||
debug("%s", "propagating local clear_tty_tostop_on_exit true value to shared tty_tostop_added flag");
|
||||
state->cursor.shared->tty_tostop_added = true;
|
||||
}
|
||||
|
||||
@@ -460,7 +436,7 @@ void pv_crs_init(pvstate_t state)
|
||||
* initial ypos.
|
||||
*/
|
||||
if (state->cursor.y_start > 0)
|
||||
pv_write_retry(STDERR_FILENO, "\n", 1);
|
||||
pv_tty_write(state, "\n", 1);
|
||||
pv_crs_unlock(state, terminalfd);
|
||||
|
||||
if (state->cursor.y_start < 1)
|
||||
@@ -493,6 +469,11 @@ static void pv_crs_reinit(pvstate_t state)
|
||||
{
|
||||
debug("%s", "reinit");
|
||||
|
||||
if (1 == state->flag.suspend_stderr) {
|
||||
debug("%s", "reinit abandoned - stderr is suspended");
|
||||
return;
|
||||
}
|
||||
|
||||
pv_crs_lock(state, STDERR_FILENO);
|
||||
|
||||
state->cursor.needreinit--;
|
||||
@@ -587,9 +568,9 @@ void pv_crs_update(pvstate_t state, const char *output_line)
|
||||
memset(cup_cmd, 0, sizeof(cup_cmd));
|
||||
(void) pv_snprintf(cup_cmd, sizeof(cup_cmd), "\033[%u;1H", state->control.height);
|
||||
cup_cmd_length = strlen(cup_cmd); /* flawfinder: ignore */
|
||||
pv_write_retry(STDERR_FILENO, cup_cmd, cup_cmd_length);
|
||||
pv_tty_write(state, cup_cmd, cup_cmd_length);
|
||||
for (; offs > 0; offs--) {
|
||||
pv_write_retry(STDERR_FILENO, "\n", 1);
|
||||
pv_tty_write(state, "\n", 1);
|
||||
}
|
||||
|
||||
pv_crs_unlock(state, STDERR_FILENO);
|
||||
@@ -622,8 +603,8 @@ void pv_crs_update(pvstate_t state, const char *output_line)
|
||||
|
||||
pv_crs_lock(state, STDERR_FILENO);
|
||||
|
||||
pv_write_retry(STDERR_FILENO, cup_cmd, cup_cmd_length);
|
||||
pv_write_retry(STDERR_FILENO, output_line, output_line_length);
|
||||
pv_tty_write(state, cup_cmd, cup_cmd_length);
|
||||
pv_tty_write(state, output_line, output_line_length);
|
||||
|
||||
pv_crs_unlock(state, STDERR_FILENO);
|
||||
}
|
||||
@@ -662,7 +643,7 @@ void pv_crs_fini(pvstate_t state)
|
||||
|
||||
pv_crs_lock(state, STDERR_FILENO);
|
||||
|
||||
pv_write_retry(STDERR_FILENO, cup_cmd, strlen(cup_cmd)); /* flawfinder: ignore */
|
||||
pv_tty_write(state, cup_cmd, strlen(cup_cmd)); /* flawfinder: ignore */
|
||||
/* flawfinder - pv_snprintf() always \0-terminates (see above). */
|
||||
|
||||
#ifdef HAVE_IPC
|
||||
@@ -672,9 +653,10 @@ void pv_crs_fini(pvstate_t state)
|
||||
* it.
|
||||
*/
|
||||
if ((!state->cursor.noipc) && (NULL != state->cursor.shared) && state->cursor.shared->tty_tostop_added) {
|
||||
if (!state->signal.pv_tty_tostop_added) {
|
||||
debug("%s", "propagating shared tty_tostop_added true value to local flag");
|
||||
state->signal.pv_tty_tostop_added = true;
|
||||
if (0 == state->flag.clear_tty_tostop_on_exit) {
|
||||
debug("%s",
|
||||
"propagating shared tty_tostop_added true value to local clear_tty_tostop_on_exit flag");
|
||||
state->flag.clear_tty_tostop_on_exit = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -707,5 +689,3 @@ void pv_crs_fini(pvstate_t state)
|
||||
(void) remove(state->cursor.lock_file);
|
||||
}
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
||||
+352
-338
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Functions relating to elapsed time.
|
||||
*
|
||||
* Copyright 2023 Andrew Wood
|
||||
* Copyright 2023-2024 Andrew Wood
|
||||
*
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
@@ -21,7 +21,7 @@
|
||||
* suspended. See clock_gettime(2) with CLOCK_MONOTONIC.
|
||||
*
|
||||
* The read should not fail; if it does, the program is aborted with exit
|
||||
* status 16.
|
||||
* status 16 (transfer error).
|
||||
*/
|
||||
void pv_elapsedtime_read(struct timespec *return_time)
|
||||
{
|
||||
@@ -29,7 +29,7 @@ void pv_elapsedtime_read(struct timespec *return_time)
|
||||
if (0 != clock_gettime(CLOCK_MONOTONIC, return_time)) {
|
||||
fprintf(stderr, "%s: %s: %s\n", PACKAGE_NAME, "clock_gettime", strerror(errno));
|
||||
/*@-exitarg@ *//* we explicitly want a special exit status */
|
||||
exit(16);
|
||||
exit(PV_ERROREXIT_TRANSFER);
|
||||
/*@+exitarg@ */
|
||||
}
|
||||
/*@+unrecog@ */
|
||||
@@ -251,5 +251,3 @@ void pv_nanosleep(long long nanoseconds)
|
||||
/*@+null@ *//* splint doesn't know about select() */
|
||||
#endif
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
||||
+27
-28
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Functions for opening and closing files, and calculating their size.
|
||||
*
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2024 Andrew Wood
|
||||
*
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
@@ -127,26 +127,27 @@ static off_t pv_calc_total_bytes(pvstate_t state)
|
||||
* input, but we are writing to a block device, then use the size of
|
||||
* the output block device.
|
||||
*
|
||||
* Further modified to check that stdout is not in append-only mode
|
||||
* Further modified to check that output is not in append-only mode
|
||||
* and that we can seek back to the start after getting the size.
|
||||
*/
|
||||
if (total < 1) {
|
||||
int rc;
|
||||
|
||||
rc = fstat(STDOUT_FILENO, &sb);
|
||||
rc = fstat(state->control.output_fd, &sb);
|
||||
|
||||
if ((0 == rc) && S_ISBLK(sb.st_mode)
|
||||
&& (0 == (fcntl(STDOUT_FILENO, F_GETFL) & O_APPEND))) {
|
||||
&& (0 == (fcntl(state->control.output_fd, F_GETFL) & O_APPEND))) {
|
||||
off_t end_position;
|
||||
end_position = lseek(STDOUT_FILENO, 0, SEEK_END);
|
||||
end_position = lseek(state->control.output_fd, 0, SEEK_END);
|
||||
total = 0;
|
||||
if (end_position > 0) {
|
||||
total = end_position;
|
||||
}
|
||||
if (lseek(STDOUT_FILENO, 0, SEEK_SET) != 0) {
|
||||
pv_error(state, "%s: %s: %s", "(stdout)",
|
||||
if (lseek(state->control.output_fd, 0, SEEK_SET) != 0) {
|
||||
pv_error(state, "%s: %s: %s",
|
||||
NULL == state->control.output_name ? "(null)" : state->control.output_name,
|
||||
_("failed to seek to start of output"), strerror(errno));
|
||||
state->status.exit_status |= 2;
|
||||
state->status.exit_status |= PV_ERROREXIT_ACCESS;
|
||||
}
|
||||
/*
|
||||
* If we worked out a size, then set the
|
||||
@@ -228,7 +229,7 @@ static off_t pv_calc_total_lines(pvstate_t state)
|
||||
*/
|
||||
if (numread < 0) {
|
||||
pv_error(state, "%s: %s", state->files.filename[file_idx], strerror(errno));
|
||||
state->status.exit_status |= 2;
|
||||
state->status.exit_status |= PV_ERROREXIT_ACCESS;
|
||||
break;
|
||||
} else if (0 == numread) {
|
||||
break;
|
||||
@@ -246,7 +247,7 @@ static off_t pv_calc_total_lines(pvstate_t state)
|
||||
|
||||
if (0 != lseek(fd, 0, SEEK_SET)) {
|
||||
pv_error(state, "%s: %s", state->files.filename[file_idx], strerror(errno));
|
||||
state->status.exit_status |= 2;
|
||||
state->status.exit_status |= PV_ERROREXIT_ACCESS;
|
||||
}
|
||||
|
||||
(void) close(fd);
|
||||
@@ -277,7 +278,7 @@ off_t pv_calc_total_size(pvstate_t state)
|
||||
* Close the given file descriptor and open the next one, whose number in
|
||||
* the list is "filenum", returning the new file descriptor (or negative on
|
||||
* error). It is an error if the next input file is the same as the file
|
||||
* stdout is pointing to.
|
||||
* the output is pointing to.
|
||||
*
|
||||
* Updates state->status.current_input_file in the process.
|
||||
*/
|
||||
@@ -286,19 +287,19 @@ int pv_next_file(pvstate_t state, unsigned int filenum, int oldfd)
|
||||
struct stat isb;
|
||||
struct stat osb;
|
||||
int fd;
|
||||
bool input_file_is_stdout;
|
||||
bool input_file_is_output;
|
||||
|
||||
if (oldfd >= 0) {
|
||||
if (0 != close(oldfd)) {
|
||||
pv_error(state, "%s: %s", _("failed to close file"), strerror(errno));
|
||||
state->status.exit_status |= 8;
|
||||
state->status.exit_status |= PV_ERROREXIT_TRANSITION;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (filenum >= state->files.file_count) {
|
||||
debug("%s: %d >= %d", "filenum too large", filenum, state->files.file_count);
|
||||
state->status.exit_status |= 8;
|
||||
state->status.exit_status |= PV_ERROREXIT_TRANSITION;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -314,7 +315,7 @@ int pv_next_file(pvstate_t state, unsigned int filenum, int oldfd)
|
||||
if (fd < 0) {
|
||||
pv_error(state, "%s: %s: %s",
|
||||
_("failed to read file"), state->files.filename[filenum], strerror(errno));
|
||||
state->status.exit_status |= 2;
|
||||
state->status.exit_status |= PV_ERROREXIT_ACCESS;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -323,37 +324,37 @@ int pv_next_file(pvstate_t state, unsigned int filenum, int oldfd)
|
||||
pv_error(state, "%s: %s: %s", _("failed to stat file"),
|
||||
NULL == state->files.filename ? "-" : state->files.filename[filenum], strerror(errno));
|
||||
(void) close(fd);
|
||||
state->status.exit_status |= 2;
|
||||
state->status.exit_status |= PV_ERROREXIT_ACCESS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (0 != fstat(STDOUT_FILENO, &osb)) {
|
||||
if (0 != fstat(state->control.output_fd, &osb)) {
|
||||
pv_error(state, "%s: %s", _("failed to stat output file"), strerror(errno));
|
||||
(void) close(fd);
|
||||
state->status.exit_status |= 2;
|
||||
state->status.exit_status |= PV_ERROREXIT_ACCESS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that this new input file is not the same as stdout's
|
||||
* Check that this new input file is not the same as output's
|
||||
* destination. This restriction is ignored for anything other
|
||||
* than a regular file or block device.
|
||||
*/
|
||||
input_file_is_stdout = true;
|
||||
input_file_is_output = true;
|
||||
if (isb.st_dev != osb.st_dev)
|
||||
input_file_is_stdout = false;
|
||||
input_file_is_output = false;
|
||||
if (isb.st_ino != osb.st_ino)
|
||||
input_file_is_stdout = false;
|
||||
input_file_is_output = false;
|
||||
if (0 != isatty(fd))
|
||||
input_file_is_stdout = false;
|
||||
input_file_is_output = false;
|
||||
if ((!S_ISREG(isb.st_mode)) && (!S_ISBLK(isb.st_mode)))
|
||||
input_file_is_stdout = false;
|
||||
input_file_is_output = false;
|
||||
|
||||
if (input_file_is_stdout) {
|
||||
if (input_file_is_output) {
|
||||
pv_error(state, "%s: %s", _("input file is output file"),
|
||||
NULL == state->files.filename ? "-" : state->files.filename[filenum]);
|
||||
(void) close(fd);
|
||||
state->status.exit_status |= 4;
|
||||
state->status.exit_status |= PV_ERROREXIT_OUROBOROS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -446,5 +447,3 @@ int pv_next_file(pvstate_t state, unsigned int filenum, int oldfd)
|
||||
/*@+onlytrans@ */
|
||||
/*@+observertrans@ */
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
||||
+301
-87
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Functions providing the main transfer or file descriptor watching loop.
|
||||
*
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2024 Andrew Wood
|
||||
*
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
@@ -24,6 +24,32 @@
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#if HAVE_MATH_H
|
||||
#include <math.h>
|
||||
#endif
|
||||
|
||||
|
||||
#if HAVE_SQRTL
|
||||
#else
|
||||
/*
|
||||
* Square root of a long double. Adapted from iputils ping/ping_common.c.
|
||||
*/
|
||||
static long ldsqrt(long double value)
|
||||
{
|
||||
long double previous = (long double) LLONG_MAX;
|
||||
long double result = value;
|
||||
|
||||
if (result > 0) {
|
||||
while (result < previous) {
|
||||
previous = result;
|
||||
result = (result + (value / result)) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Pipe data from a list of files to standard output, giving information
|
||||
@@ -34,15 +60,15 @@
|
||||
int pv_main_loop(pvstate_t state)
|
||||
{
|
||||
long lineswritten;
|
||||
off_t total_written, transferred_since_last, cansend;
|
||||
off_t cansend;
|
||||
ssize_t written;
|
||||
long double target;
|
||||
bool eof_in, eof_out, final_update;
|
||||
struct timespec start_time, next_update, next_ratecheck, cur_time;
|
||||
struct timespec init_time, next_remotecheck, transfer_elapsed;
|
||||
long double elapsed_seconds;
|
||||
int fd;
|
||||
int input_fd, output_fd;
|
||||
unsigned int file_idx;
|
||||
bool output_is_pipe;
|
||||
|
||||
/*
|
||||
* "written" is ALWAYS bytes written by the last transfer.
|
||||
@@ -50,26 +76,56 @@ int pv_main_loop(pvstate_t state)
|
||||
* "lineswritten" is the lines written by the last transfer,
|
||||
* but is only updated in line mode.
|
||||
*
|
||||
* "total_written" is the total bytes written since the start,
|
||||
* or in line mode, the total lines written since the start.
|
||||
*
|
||||
* "transferred_since_last" is the bytes written since the last
|
||||
* display, or in line mode, the lines written since the last
|
||||
* display.
|
||||
* "state->transfer.total_written" is the total bytes written since
|
||||
* the start, or in line mode, the total lines written since the
|
||||
* start.
|
||||
*
|
||||
* The remaining variables are all unchanged by linemode.
|
||||
*/
|
||||
|
||||
fd = -1;
|
||||
input_fd = -1;
|
||||
|
||||
output_fd = state->control.output_fd;
|
||||
if (output_fd < 0)
|
||||
output_fd = STDOUT_FILENO;
|
||||
|
||||
/* Determine whether the output is a pipe. */
|
||||
output_is_pipe = false;
|
||||
{
|
||||
struct stat sb;
|
||||
memset(&sb, 0, sizeof(sb));
|
||||
if (0 == fstat(output_fd, &sb)) {
|
||||
/*@-type@ */
|
||||
if ((sb.st_mode & S_IFMT) == S_IFIFO) {
|
||||
output_is_pipe = true;
|
||||
debug("%s", "output is a pipe");
|
||||
}
|
||||
/*@+type@ *//* splint says st_mode is __mode_t, not mode_t */
|
||||
} else {
|
||||
debug("%s(%d): %s", "fstat", output_fd, strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that we could reduce the size of the output pipe buffer like
|
||||
* this, to avoid the case where we write a load of data and it just
|
||||
* goes into the buffer so we think we're done, but the consumer
|
||||
* takes ages to process it:
|
||||
*
|
||||
* fcntl(output_fd, F_SETPIPE_SZ, 4096);
|
||||
*
|
||||
* If we can peek at how much has been consumed by the other end, we
|
||||
* don't need to.
|
||||
*/
|
||||
|
||||
pv_crs_init(state);
|
||||
|
||||
eof_in = false;
|
||||
eof_out = false;
|
||||
total_written = 0;
|
||||
state->transfer.total_written = 0;
|
||||
lineswritten = 0;
|
||||
transferred_since_last = 0;
|
||||
state->display.initial_offset = 0;
|
||||
state->transfer.written_but_not_consumed = 0;
|
||||
|
||||
memset(&cur_time, 0, sizeof(cur_time));
|
||||
memset(&start_time, 0, sizeof(start_time));
|
||||
@@ -98,32 +154,31 @@ int pv_main_loop(pvstate_t state)
|
||||
/*
|
||||
* Open the first readable input file.
|
||||
*/
|
||||
fd = -1;
|
||||
while (fd < 0 && file_idx < state->files.file_count) {
|
||||
fd = pv_next_file(state, file_idx, -1);
|
||||
if (fd < 0)
|
||||
input_fd = -1;
|
||||
while (input_fd < 0 && file_idx < state->files.file_count) {
|
||||
input_fd = pv_next_file(state, file_idx, -1);
|
||||
if (input_fd < 0)
|
||||
file_idx++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Exit early if there was no readable input file.
|
||||
*/
|
||||
if (fd < 0) {
|
||||
if (input_fd < 0) {
|
||||
if (state->control.cursor)
|
||||
pv_crs_fini(state);
|
||||
return state->status.exit_status;
|
||||
}
|
||||
#if HAVE_POSIX_FADVISE
|
||||
/* Advise the OS that we will only be reading sequentially. */
|
||||
(void) posix_fadvise(fd, 0, 0, POSIX_FADV_SEQUENTIAL);
|
||||
(void) posix_fadvise(input_fd, 0, 0, POSIX_FADV_SEQUENTIAL);
|
||||
#endif
|
||||
|
||||
#ifdef O_DIRECT
|
||||
/*
|
||||
* Set or clear O_DIRECT on the output.
|
||||
*/
|
||||
if (0 !=
|
||||
fcntl(STDOUT_FILENO, F_SETFL, (state->control.direct_io ? O_DIRECT : 0) | fcntl(STDOUT_FILENO, F_GETFL))) {
|
||||
if (0 != fcntl(output_fd, F_SETFL, (state->control.direct_io ? O_DIRECT : 0) | fcntl(output_fd, F_GETFL))) {
|
||||
debug("%s: %s", "fcntl", strerror(errno));
|
||||
}
|
||||
state->control.direct_io_changed = false;
|
||||
@@ -137,7 +192,7 @@ int pv_main_loop(pvstate_t state)
|
||||
if (0 == state->control.target_buffer_size) {
|
||||
struct stat sb;
|
||||
memset(&sb, 0, sizeof(sb));
|
||||
if (0 == fstat(fd, &sb)) {
|
||||
if (0 == fstat(input_fd, &sb)) {
|
||||
size_t sz;
|
||||
sz = (size_t) (sb.st_blksize * 32);
|
||||
if (sz > BUFFER_SIZE_MAX) {
|
||||
@@ -151,6 +206,11 @@ int pv_main_loop(pvstate_t state)
|
||||
if (0 == state->control.target_buffer_size)
|
||||
state->control.target_buffer_size = BUFFER_SIZE;
|
||||
|
||||
/*
|
||||
* Repeat until eof_in is true, eof_out is true, and final_update is
|
||||
* true.
|
||||
*/
|
||||
|
||||
while ((!(eof_in && eof_out)) || (!final_update)) {
|
||||
|
||||
cansend = 0;
|
||||
@@ -187,11 +247,12 @@ int pv_main_loop(pvstate_t state)
|
||||
* try to write more than we're allowed to.
|
||||
*/
|
||||
if ((0 < state->control.size) && (state->control.stop_at_size)) {
|
||||
if ((state->control.size < (total_written + cansend))
|
||||
if ((state->control.size < (state->transfer.total_written + cansend))
|
||||
|| ((0 == cansend)
|
||||
&& (0 == state->control.rate_limit))) {
|
||||
cansend = state->control.size - total_written;
|
||||
cansend = state->control.size - state->transfer.total_written;
|
||||
if (0 >= cansend) {
|
||||
debug("%s", "write limit reached (size explicitly set) - setting EOF flags");
|
||||
eof_in = true;
|
||||
eof_out = true;
|
||||
}
|
||||
@@ -202,45 +263,136 @@ int pv_main_loop(pvstate_t state)
|
||||
&& (0 >= cansend) && eof_in && eof_out) {
|
||||
written = 0;
|
||||
} else {
|
||||
written = pv_transfer(state, fd, &eof_in, &eof_out, cansend, &lineswritten);
|
||||
written = pv_transfer(state, input_fd, &eof_in, &eof_out, cansend, &lineswritten);
|
||||
}
|
||||
|
||||
/* End on write error. */
|
||||
if (written < 0) {
|
||||
debug("%s: %s", "write error from pv_transfer", strerror(errno));
|
||||
if (state->control.cursor)
|
||||
pv_crs_fini(state);
|
||||
return state->status.exit_status;
|
||||
}
|
||||
|
||||
if (state->control.linemode) {
|
||||
transferred_since_last += lineswritten;
|
||||
total_written += lineswritten;
|
||||
state->transfer.total_written += lineswritten;
|
||||
if (state->control.rate_limit > 0)
|
||||
target -= lineswritten;
|
||||
} else {
|
||||
transferred_since_last += written;
|
||||
total_written += written;
|
||||
state->transfer.total_written += written;
|
||||
if (state->control.rate_limit > 0)
|
||||
target -= written;
|
||||
}
|
||||
|
||||
#ifdef FIONREAD
|
||||
/*
|
||||
* If writing to a pipe, look at how much is sitting in the
|
||||
* pipe buffer waiting for the receiver to read.
|
||||
*/
|
||||
if (output_is_pipe) {
|
||||
int nbytes;
|
||||
nbytes = 0;
|
||||
if (0 != state->flag.pipe_closed) {
|
||||
if (0 != state->transfer.written_but_not_consumed)
|
||||
debug("%s",
|
||||
"clearing written_but_not_consumed because the output pipe was closed");
|
||||
state->transfer.written_but_not_consumed = 0;
|
||||
} else if (0 == ioctl(output_fd, FIONREAD, &nbytes)) {
|
||||
if (nbytes >= 0) {
|
||||
if (((size_t) nbytes) != state->transfer.written_but_not_consumed)
|
||||
debug("%s: %d", "written_but_not_consumed is now", nbytes);
|
||||
state->transfer.written_but_not_consumed = (size_t) nbytes;
|
||||
} else {
|
||||
debug("%s: %d", "FIONREAD gave a negative byte count", nbytes);
|
||||
state->transfer.written_but_not_consumed = 0;
|
||||
}
|
||||
} else {
|
||||
debug("%s(%d,%s): %s", "ioctl", output_fd, "FIONREAD", strerror(errno));
|
||||
state->transfer.written_but_not_consumed = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
state->transfer.transferred = state->transfer.total_written;
|
||||
if (output_is_pipe && !state->control.linemode) {
|
||||
/*
|
||||
* Writing bytes to a pipe - the amount transferred
|
||||
* to the receiver is the total amount we've
|
||||
* written, minus what's sitting in the pipe buffer
|
||||
* waiting for the receiver to consume it.
|
||||
*/
|
||||
state->transfer.transferred -= state->transfer.written_but_not_consumed;
|
||||
|
||||
} else if (output_is_pipe && state->control.linemode && state->transfer.written_but_not_consumed > 0
|
||||
&& NULL != state->transfer.line_positions) {
|
||||
/*
|
||||
* Writing lines to a pipe - similar to above, but
|
||||
* we have to work out how many lines the
|
||||
* yet-to-be-consumed data in the buffer equates to.
|
||||
*
|
||||
* To do this, we walk backwards through our record
|
||||
* of the line positions in the output we've
|
||||
* written.
|
||||
*/
|
||||
off_t last_consumed_position =
|
||||
state->transfer.last_output_position - state->transfer.written_but_not_consumed;
|
||||
size_t lines_not_consumed = 0;
|
||||
size_t line_from_end = 0;
|
||||
|
||||
/*
|
||||
* positions[head-1] = position of last separator written
|
||||
* positions[head-2] = position of second last separator written
|
||||
* etc
|
||||
*
|
||||
* We start at [head-1] and go backwards, wrapping
|
||||
* around as it's a circular buffer, stopping at the
|
||||
* length (number of positions stored), or when we
|
||||
* have gone before the last consumed position.
|
||||
*/
|
||||
for (line_from_end = 0; line_from_end < state->transfer.line_positions_length; line_from_end++) {
|
||||
size_t array_index;
|
||||
array_index =
|
||||
state->transfer.line_positions_head + state->transfer.line_positions_capacity -
|
||||
line_from_end - 1;
|
||||
while (array_index >= state->transfer.line_positions_capacity)
|
||||
array_index -= state->transfer.line_positions_capacity;
|
||||
if (state->transfer.line_positions[array_index] <= last_consumed_position)
|
||||
break;
|
||||
lines_not_consumed++;
|
||||
}
|
||||
|
||||
debug("%s: %lld -> %lld", "written_but_not_consumed bytes to lines",
|
||||
(unsigned long long) (state->transfer.written_but_not_consumed),
|
||||
(unsigned long long) lines_not_consumed);
|
||||
|
||||
state->transfer.transferred -= lines_not_consumed;
|
||||
}
|
||||
|
||||
/*
|
||||
* EOF, and files remain - advance to the next file.
|
||||
*/
|
||||
while (eof_in && eof_out && file_idx < (state->files.file_count - 1)) {
|
||||
file_idx++;
|
||||
fd = pv_next_file(state, file_idx, fd);
|
||||
if (fd >= 0) {
|
||||
input_fd = pv_next_file(state, file_idx, input_fd);
|
||||
if (input_fd >= 0) {
|
||||
eof_in = false;
|
||||
eof_out = false;
|
||||
#if HAVE_POSIX_FADVISE
|
||||
/* Advise the OS that we will only be reading sequentially. */
|
||||
(void) posix_fadvise(input_fd, 0, 0, POSIX_FADV_SEQUENTIAL);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* Now check the current time. */
|
||||
pv_elapsedtime_read(&cur_time);
|
||||
|
||||
/* If full EOF, final update, and force a display updaate. */
|
||||
if (eof_in && eof_out) {
|
||||
/*
|
||||
* If we've read everything and written everything, and the
|
||||
* output pipe buffer is empty, then set the final update
|
||||
* flag, and force a display update.
|
||||
*/
|
||||
if (eof_in && eof_out && 0 == state->transfer.written_but_not_consumed) {
|
||||
final_update = true;
|
||||
if ((state->display.display_visible)
|
||||
|| (state->control.delay_start < 0.001)) {
|
||||
@@ -248,8 +400,11 @@ int pv_main_loop(pvstate_t state)
|
||||
}
|
||||
}
|
||||
|
||||
/* Just go round the loop again if there's no display. */
|
||||
if (state->control.no_display)
|
||||
/*
|
||||
* Just go round the loop again if there's no display and
|
||||
* we're not reporting statistics.
|
||||
*/
|
||||
if (state->control.no_display && !state->control.show_stats)
|
||||
continue;
|
||||
|
||||
/*
|
||||
@@ -318,10 +473,7 @@ int pv_main_loop(pvstate_t state)
|
||||
memset(&transfer_elapsed, 0, sizeof(transfer_elapsed));
|
||||
pv_elapsedtime_subtract(&transfer_elapsed, &cur_time, &init_time);
|
||||
|
||||
elapsed_seconds = pv_elapsedtime_seconds(&transfer_elapsed);
|
||||
|
||||
if (final_update)
|
||||
transferred_since_last = -1;
|
||||
state->transfer.elapsed_seconds = pv_elapsedtime_seconds(&transfer_elapsed);
|
||||
|
||||
/* Resize the display, if a resize signal was received. */
|
||||
if (1 == state->flag.terminal_resized) {
|
||||
@@ -339,24 +491,77 @@ int pv_main_loop(pvstate_t state)
|
||||
state->control.height = new_height;
|
||||
}
|
||||
|
||||
pv_display(state, elapsed_seconds, transferred_since_last, total_written);
|
||||
|
||||
transferred_since_last = 0;
|
||||
if (state->control.no_display) {
|
||||
/* If there's no display, calculate rate for the statistics. */
|
||||
pv_calculate_transfer_rate(state, final_update);
|
||||
} else {
|
||||
/* Produce the display. */
|
||||
pv_display(state, final_update);
|
||||
}
|
||||
}
|
||||
|
||||
debug("%s: %s=%s, %s=%s", "loop ended", "eof_in", eof_in ? "true" : "false", "eof_out",
|
||||
eof_out ? "true" : "false");
|
||||
|
||||
if (state->control.cursor) {
|
||||
pv_crs_fini(state);
|
||||
} else {
|
||||
if ((!state->control.numeric) && (!state->control.no_display)
|
||||
&& (state->display.display_visible))
|
||||
pv_write_retry(STDERR_FILENO, "\n", 1);
|
||||
pv_tty_write(state, "\n", 1);
|
||||
}
|
||||
|
||||
if (1 == state->flag.trigger_exit)
|
||||
state->status.exit_status |= 32;
|
||||
state->status.exit_status |= PV_ERROREXIT_SIGNAL;
|
||||
|
||||
if (fd >= 0)
|
||||
(void) close(fd);
|
||||
if (input_fd >= 0)
|
||||
(void) close(input_fd);
|
||||
|
||||
/* Calculate and display the transfer statistics. */
|
||||
if (state->control.show_stats && state->calc.measurements_taken > 0) {
|
||||
char stats_buf[256]; /* flawfinder: ignore */
|
||||
long double rate_mean, rate_variance, rate_deviation;
|
||||
int stats_size;
|
||||
|
||||
/* flawfinder: made safe by use of pv_snprintf() */
|
||||
|
||||
rate_mean = state->calc.rate_sum / ((long double) (state->calc.measurements_taken));
|
||||
rate_variance =
|
||||
(state->calc.ratesquared_sum / ((long double) (state->calc.measurements_taken))) -
|
||||
(rate_mean * rate_mean);
|
||||
#if HAVE_SQRTL
|
||||
rate_deviation = sqrtl(rate_variance);
|
||||
#else
|
||||
rate_deviation = ldsqrt(rate_variance);
|
||||
#endif
|
||||
|
||||
debug("%s: %ld", "measurements taken", state->calc.measurements_taken);
|
||||
debug("%s: %.3Lf", "rate_sum", state->calc.rate_sum);
|
||||
debug("%s: %.3Lf", "ratesquared_sum", state->calc.ratesquared_sum);
|
||||
debug("%s: %.3Lf", "rate_mean", rate_mean);
|
||||
debug("%s: %.3Lf", "rate_variance", rate_variance);
|
||||
debug("%s: %.3Lf", "rate_deviation", rate_deviation);
|
||||
|
||||
memset(stats_buf, 0, sizeof(stats_buf));
|
||||
stats_size =
|
||||
pv_snprintf(stats_buf, sizeof(stats_buf), "%s = %.3Lf/%.3Lf/%.3Lf/%.3Lf %s\n",
|
||||
_("rate min/avg/max/mdev"), state->calc.rate_min, rate_mean, state->calc.rate_max,
|
||||
rate_deviation, state->control.bits ? _("b/s") : _("B/s"));
|
||||
|
||||
if (stats_size > 0 && stats_size < (int) (sizeof(stats_buf)))
|
||||
pv_tty_write(state, stats_buf, (size_t) stats_size);
|
||||
} else if (state->control.show_stats && state->calc.measurements_taken < 1) {
|
||||
char msg_buf[256]; /* flawfinder: ignore */
|
||||
int msg_size;
|
||||
|
||||
/* flawfinder: made safe by use of pv_snprintf() */
|
||||
|
||||
memset(msg_buf, 0, sizeof(msg_buf));
|
||||
msg_size = pv_snprintf(msg_buf, sizeof(msg_buf), "%s\n", _("rate not measured"));
|
||||
|
||||
if (msg_size > 0 && msg_size < (int) (sizeof(msg_buf)))
|
||||
pv_tty_write(state, msg_buf, (size_t) msg_size);
|
||||
}
|
||||
|
||||
return state->status.exit_status;
|
||||
}
|
||||
@@ -372,10 +577,9 @@ int pv_main_loop(pvstate_t state)
|
||||
int pv_watchfd_loop(pvstate_t state)
|
||||
{
|
||||
struct pvwatchfd_s info;
|
||||
off_t position_now, total_written, transferred_since_last;
|
||||
off_t position_now;
|
||||
struct timespec next_update, cur_time;
|
||||
struct timespec init_time, next_remotecheck, transfer_elapsed;
|
||||
long double elapsed_seconds;
|
||||
bool ended, first_check;
|
||||
int rc;
|
||||
|
||||
@@ -384,7 +588,7 @@ int pv_watchfd_loop(pvstate_t state)
|
||||
info.watch_fd = state->control.watch_fd;
|
||||
rc = pv_watchfd_info(state, &info, false);
|
||||
if (0 != rc) {
|
||||
state->status.exit_status |= 2;
|
||||
state->status.exit_status |= PV_ERROREXIT_ACCESS;
|
||||
/*@-compdestroy@ */
|
||||
return state->status.exit_status;
|
||||
/*@+compdestroy@ */
|
||||
@@ -422,8 +626,6 @@ int pv_watchfd_loop(pvstate_t state)
|
||||
pv_elapsedtime_add_nsec(&next_update, (long long) (1000000000.0 * state->control.interval));
|
||||
|
||||
ended = false;
|
||||
total_written = 0;
|
||||
transferred_since_last = 0;
|
||||
first_check = true;
|
||||
|
||||
while (!ended) {
|
||||
@@ -443,12 +645,12 @@ int pv_watchfd_loop(pvstate_t state)
|
||||
if (position_now < 0) {
|
||||
ended = true;
|
||||
} else {
|
||||
transferred_since_last += position_now - total_written;
|
||||
total_written = position_now;
|
||||
if (first_check) {
|
||||
state->display.initial_offset = position_now;
|
||||
first_check = false;
|
||||
}
|
||||
state->transfer.transferred = position_now;
|
||||
state->transfer.total_written = position_now;
|
||||
}
|
||||
|
||||
pv_elapsedtime_read(&cur_time);
|
||||
@@ -485,10 +687,7 @@ int pv_watchfd_loop(pvstate_t state)
|
||||
*/
|
||||
pv_elapsedtime_subtract(&transfer_elapsed, &cur_time, &init_time);
|
||||
|
||||
elapsed_seconds = pv_elapsedtime_seconds(&transfer_elapsed);
|
||||
|
||||
if (ended)
|
||||
transferred_since_last = -1;
|
||||
state->transfer.elapsed_seconds = pv_elapsedtime_seconds(&transfer_elapsed);
|
||||
|
||||
/* Resize the display, if a resize signal was received. */
|
||||
if (1 == state->flag.terminal_resized) {
|
||||
@@ -506,16 +705,14 @@ int pv_watchfd_loop(pvstate_t state)
|
||||
state->control.height = new_height;
|
||||
}
|
||||
|
||||
pv_display(state, elapsed_seconds, transferred_since_last, total_written);
|
||||
|
||||
transferred_since_last = 0;
|
||||
pv_display(state, ended);
|
||||
}
|
||||
|
||||
if (!state->control.numeric)
|
||||
pv_write_retry(STDERR_FILENO, "\n", 1);
|
||||
pv_tty_write(state, "\n", 1);
|
||||
|
||||
if (1 == state->flag.trigger_exit)
|
||||
state->status.exit_status |= 32;
|
||||
state->status.exit_status |= PV_ERROREXIT_SIGNAL;
|
||||
|
||||
/*
|
||||
* Free the state structure specific to this file descriptor.
|
||||
@@ -568,8 +765,8 @@ int pv_watchpid_loop(pvstate_t state)
|
||||
*/
|
||||
if (kill(state->control.watch_pid, 0) != 0) {
|
||||
pv_error(state, "%s %u: %s", _("pid"), state->control.watch_pid, strerror(errno));
|
||||
state->status.exit_status |= 2;
|
||||
return 2;
|
||||
state->status.exit_status |= PV_ERROREXIT_ACCESS;
|
||||
return PV_ERROREXIT_ACCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -619,10 +816,10 @@ int pv_watchpid_loop(pvstate_t state)
|
||||
if (kill(state->control.watch_pid, 0) != 0) {
|
||||
if (first_pass) {
|
||||
pv_error(state, "%s %u: %s", _("pid"), state->control.watch_pid, strerror(errno));
|
||||
state->status.exit_status |= 2;
|
||||
state->status.exit_status |= PV_ERROREXIT_ACCESS;
|
||||
if (NULL != info_array)
|
||||
free(info_array);
|
||||
return 2;
|
||||
return PV_ERROREXIT_ACCESS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -660,10 +857,10 @@ int pv_watchpid_loop(pvstate_t state)
|
||||
if (rc != 0) {
|
||||
if (first_pass) {
|
||||
pv_error(state, "%s %u: %s", _("pid"), state->control.watch_pid, strerror(errno));
|
||||
state->status.exit_status |= 2;
|
||||
state->status.exit_status |= PV_ERROREXIT_ACCESS;
|
||||
if (NULL != info_array)
|
||||
free(info_array);
|
||||
return 2;
|
||||
return PV_ERROREXIT_ACCESS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -672,9 +869,8 @@ int pv_watchpid_loop(pvstate_t state)
|
||||
displayed_lines = 0;
|
||||
|
||||
for (fd = 0; fd < FD_SETSIZE && NULL != info_array; fd++) {
|
||||
off_t position_now, transferred_since_last;
|
||||
off_t position_now;
|
||||
struct timespec init_time, transfer_elapsed;
|
||||
long double elapsed_seconds;
|
||||
|
||||
if (displayed_lines >= (int) (state->control.height))
|
||||
break;
|
||||
@@ -692,6 +888,11 @@ int pv_watchpid_loop(pvstate_t state)
|
||||
if (pv_watchfd_changed(&(info_array[idx]))) {
|
||||
fd_to_idx[fd] = -1;
|
||||
info_array[idx].watch_pid = 0;
|
||||
if (NULL != info_array[idx].state)
|
||||
pv_state_free(info_array[idx].state);
|
||||
/*@-mustfreeonly@ *//* not a leak - we've just free()d it. */
|
||||
info_array[idx].state = NULL;
|
||||
/*@+mustfreeonly@ */
|
||||
debug("%s %d: %s", "fd", fd, "removing");
|
||||
}
|
||||
continue;
|
||||
@@ -711,11 +912,15 @@ int pv_watchpid_loop(pvstate_t state)
|
||||
if (position_now < 0) {
|
||||
fd_to_idx[fd] = -1;
|
||||
info_array[idx].watch_pid = 0;
|
||||
if (NULL != info_array[idx].state)
|
||||
pv_state_free(info_array[idx].state);
|
||||
/*@-mustfreeonly@ *//* not a leak - we've just free()d it. */
|
||||
info_array[idx].state = NULL;
|
||||
/*@+mustfreeonly@ */
|
||||
debug("%s %d: %s", "fd", fd, "removing");
|
||||
continue;
|
||||
}
|
||||
|
||||
transferred_since_last = position_now - info_array[idx].position;
|
||||
info_array[idx].position = position_now;
|
||||
|
||||
memset(&init_time, 0, sizeof(init_time));
|
||||
@@ -733,18 +938,29 @@ int pv_watchpid_loop(pvstate_t state)
|
||||
*/
|
||||
pv_elapsedtime_subtract(&transfer_elapsed, &cur_time, &init_time);
|
||||
|
||||
elapsed_seconds = pv_elapsedtime_seconds(&transfer_elapsed);
|
||||
if (NULL != info_array[idx].state) {
|
||||
info_array[idx].state->transfer.elapsed_seconds =
|
||||
pv_elapsedtime_seconds(&transfer_elapsed);
|
||||
}
|
||||
|
||||
if (displayed_lines > 0) {
|
||||
debug("%s", "adding newline");
|
||||
pv_write_retry(STDERR_FILENO, "\n", 1);
|
||||
pv_tty_write(state, "\n", 1);
|
||||
}
|
||||
|
||||
debug("%s %d [%d]: %Lf / %Ld / %Ld", "fd", fd, idx, elapsed_seconds, transferred_since_last,
|
||||
position_now);
|
||||
if (NULL == info_array[idx].state) {
|
||||
debug("%s %d [%d]: %s / %Ld", "fd", fd, idx, "(null state)", position_now);
|
||||
} else {
|
||||
debug("%s %d [%d]: %Lf / %Ld", "fd", fd, idx,
|
||||
info_array[idx].state->transfer.elapsed_seconds, position_now);
|
||||
}
|
||||
|
||||
pv_display(info_array[idx].state, elapsed_seconds, transferred_since_last, position_now);
|
||||
displayed_lines++;
|
||||
if (NULL != info_array[idx].state) {
|
||||
info_array[idx].state->transfer.transferred = position_now;
|
||||
info_array[idx].state->transfer.total_written = position_now;
|
||||
pv_display(info_array[idx].state, false);
|
||||
displayed_lines++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -760,10 +976,10 @@ int pv_watchpid_loop(pvstate_t state)
|
||||
while (blank_lines > 0) {
|
||||
unsigned int x;
|
||||
if (displayed_lines > 0)
|
||||
pv_write_retry(STDERR_FILENO, "\n", 1);
|
||||
pv_tty_write(state, "\n", 1);
|
||||
for (x = 0; x < state->control.width; x++)
|
||||
pv_write_retry(STDERR_FILENO, " ", 1);
|
||||
pv_write_retry(STDERR_FILENO, "\r", 1);
|
||||
pv_tty_write(state, " ", 1);
|
||||
pv_tty_write(state, "\r", 1);
|
||||
blank_lines--;
|
||||
displayed_lines++;
|
||||
}
|
||||
@@ -771,7 +987,7 @@ int pv_watchpid_loop(pvstate_t state)
|
||||
debug("%s: %d", "displayed lines", displayed_lines);
|
||||
|
||||
while (displayed_lines > 1) {
|
||||
pv_write_retry(STDERR_FILENO, "\033[A", 3);
|
||||
pv_tty_write(state, "\033[A", 3);
|
||||
displayed_lines--;
|
||||
}
|
||||
}
|
||||
@@ -783,14 +999,14 @@ int pv_watchpid_loop(pvstate_t state)
|
||||
while (blank_lines > 0) {
|
||||
unsigned int x;
|
||||
for (x = 0; x < state->control.width; x++)
|
||||
pv_write_retry(STDERR_FILENO, " ", 1);
|
||||
pv_write_retry(STDERR_FILENO, "\r", 1);
|
||||
pv_tty_write(state, " ", 1);
|
||||
pv_tty_write(state, "\r", 1);
|
||||
blank_lines--;
|
||||
if (blank_lines > 0)
|
||||
pv_write_retry(STDERR_FILENO, "\n", 1);
|
||||
pv_tty_write(state, "\n", 1);
|
||||
}
|
||||
while (prev_displayed_lines > 1) {
|
||||
pv_write_retry(STDERR_FILENO, "\033[A", 3);
|
||||
pv_tty_write(state, "\033[A", 3);
|
||||
prev_displayed_lines--;
|
||||
}
|
||||
|
||||
@@ -809,5 +1025,3 @@ int pv_watchpid_loop(pvstate_t state)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
||||
+54
-16
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Functions for converting strings to numbers.
|
||||
*
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2024 Andrew Wood
|
||||
*
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
@@ -27,14 +27,16 @@ static bool pv__isdigit(char c)
|
||||
* Return the numeric value of "str", as an off_t, where "str" is expected
|
||||
* to be a sequence of digits (without a thousands separator), possibly with
|
||||
* a fractional part, optionally followed by a units suffix such as "K" for
|
||||
* kibibytes.
|
||||
* kibibytes. If "decimal_units" is true, suffixes are interpreted as
|
||||
* multiples of 1000, rather than multiples of 1024.
|
||||
*/
|
||||
off_t pv_getnum_size(const char *str)
|
||||
off_t pv_getnum_size(const char *str, bool decimal_units)
|
||||
{
|
||||
off_t integral_part = 0;
|
||||
off_t fractional_part = 0;
|
||||
unsigned int fractional_divisor = 1;
|
||||
unsigned int shift = 0;
|
||||
unsigned int binary_shift = 0;
|
||||
off_t decimal_multiplier = 0;
|
||||
|
||||
if (NULL == str)
|
||||
return (off_t) 0;
|
||||
@@ -74,7 +76,7 @@ off_t pv_getnum_size(const char *str)
|
||||
|
||||
/*
|
||||
* Parse any units given (K=KiB=*1024, M=MiB=1024KiB, G=GiB=1024MiB,
|
||||
* T=TiB=1024GiB).
|
||||
* T=TiB=1024GiB; replace 1024 with 1000 if decimal_units is true).
|
||||
*/
|
||||
if (str[0] != '\0') {
|
||||
/* Skip any spaces or tabs after the digits. */
|
||||
@@ -83,19 +85,23 @@ off_t pv_getnum_size(const char *str)
|
||||
switch (str[0]) {
|
||||
case 'k':
|
||||
case 'K':
|
||||
shift = 10;
|
||||
binary_shift = 10;
|
||||
decimal_multiplier = 1000;
|
||||
break;
|
||||
case 'm':
|
||||
case 'M':
|
||||
shift = 20;
|
||||
binary_shift = 20;
|
||||
decimal_multiplier = 1000000;
|
||||
break;
|
||||
case 'g':
|
||||
case 'G':
|
||||
shift = 30;
|
||||
binary_shift = 30;
|
||||
decimal_multiplier = 1000000000;
|
||||
break;
|
||||
case 't':
|
||||
case 'T':
|
||||
shift = 40;
|
||||
binary_shift = 40;
|
||||
decimal_multiplier = 1000000000000;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -103,14 +109,24 @@ off_t pv_getnum_size(const char *str)
|
||||
}
|
||||
|
||||
/*
|
||||
* Binary left-shift the supplied number by "shift" times, i.e.
|
||||
* If decimal_units is false, zero decimal_multiplier; if true, zero
|
||||
* binary_shift. This is so we only do one or the other.
|
||||
*/
|
||||
if (decimal_units) {
|
||||
binary_shift = 0;
|
||||
} else {
|
||||
decimal_multiplier = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Binary left-shift the supplied number by "binary_shift" times, i.e.
|
||||
* apply the given units (KiB, MiB, etc) to it, but never shift left
|
||||
* more than 30 at a time to avoid overflows.
|
||||
*/
|
||||
while (shift > 0) {
|
||||
while (binary_shift > 0) {
|
||||
unsigned int shiftby;
|
||||
|
||||
shiftby = shift;
|
||||
shiftby = binary_shift;
|
||||
if (shiftby > 30)
|
||||
shiftby = 30;
|
||||
|
||||
@@ -124,7 +140,15 @@ off_t pv_getnum_size(const char *str)
|
||||
fractional_part = (off_t) (fractional_part << shiftby);
|
||||
/*@+shiftimplementation@ */
|
||||
|
||||
shift -= shiftby;
|
||||
binary_shift -= shiftby;
|
||||
}
|
||||
|
||||
/*
|
||||
* Multiply the supplied number by the decimal multiplier.
|
||||
*/
|
||||
if (decimal_multiplier > 0) {
|
||||
integral_part = integral_part * decimal_multiplier;
|
||||
fractional_part = fractional_part * decimal_multiplier;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -183,9 +207,9 @@ double pv_getnum_interval(const char *str)
|
||||
* rules as pv_getnum_size(), expecting "str" to express a value to be used
|
||||
* as a count (such as number of screen columns, or size of a buffer).
|
||||
*/
|
||||
unsigned int pv_getnum_count(const char *str)
|
||||
unsigned int pv_getnum_count(const char *str, bool decimal_units)
|
||||
{
|
||||
return (unsigned int) pv_getnum_size(str);
|
||||
return (unsigned int) pv_getnum_size(str, decimal_units);
|
||||
}
|
||||
|
||||
|
||||
@@ -256,4 +280,18 @@ bool pv_getnum_check(const char *str, pv_numtype type)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
||||
/*
|
||||
* Return an integer representing "amount" as a percentage of "total", i.e.
|
||||
* 100*amount/total. If "total" is zero or less, return 0.
|
||||
*/
|
||||
int pv_percentage(off_t amount, const off_t total)
|
||||
{
|
||||
if (total < 1)
|
||||
return 0;
|
||||
|
||||
amount *= 100;
|
||||
amount /= total;
|
||||
|
||||
return (int) amount;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Functions for setting the process title.
|
||||
*
|
||||
* Copyright 2024 Andrew Wood
|
||||
*
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "pv.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if ! HAVE_SETPROCTITLE
|
||||
extern char **environ;
|
||||
|
||||
/*@null@*/ static char **base_argv = NULL;
|
||||
static size_t space_available = 0;
|
||||
|
||||
|
||||
/*
|
||||
* Assuming the environment comes after the command line arguments, we make
|
||||
* a duplicate of the environment array and all its values, so we can use
|
||||
* the space the environment used to occupy for the process title.
|
||||
*
|
||||
* The logic for this was derived from util-linux-ng.
|
||||
*/
|
||||
/*@-mustfreefresh@ */
|
||||
/*@-nullstate@ */
|
||||
void initproctitle(int argc, char **argv)
|
||||
{
|
||||
char **original_environment = environ;
|
||||
char **new_environment;
|
||||
size_t env_array_size, env_index;
|
||||
|
||||
/* Find the number of entries in the environment array. */
|
||||
for (env_array_size = 0; environ[env_array_size] != NULL; env_array_size++)
|
||||
continue;
|
||||
|
||||
/* Allocate a new environment array. */
|
||||
new_environment = (char **) malloc(sizeof(char *) * (env_array_size + 1));
|
||||
if (NULL == new_environment)
|
||||
return;
|
||||
|
||||
/* Duplicate the strings in the environment. */
|
||||
for (env_index = 0; original_environment[env_index] != NULL; env_index++) {
|
||||
new_environment[env_index] = pv_strdup(original_environment[env_index]);
|
||||
if (NULL == new_environment[env_index])
|
||||
return;
|
||||
}
|
||||
new_environment[env_index] = NULL;
|
||||
|
||||
base_argv = argv;
|
||||
|
||||
/* Work out how much room we have. */
|
||||
if (env_index > 0) {
|
||||
/* From argv[0] to the end of the last environment value. */
|
||||
space_available = (size_t)
|
||||
(original_environment[env_index - 1] + strlen(original_environment[env_index - 1]) - argv[0]); /* flawfinder: ignore */
|
||||
} else if (argc > 0) {
|
||||
/* No environment; from argv[0] to the end of the last argument. */
|
||||
space_available = (size_t) (argv[argc - 1] + strlen(argv[argc - 1]) - argv[0]); /* flawfinder: ignore */
|
||||
}
|
||||
|
||||
/*
|
||||
* flawfinder - we have to trust that the environment and argument
|
||||
* strings are null-terminated, since that's what the OS is supposed
|
||||
* to guarantee.
|
||||
*/
|
||||
|
||||
environ = new_environment;
|
||||
}
|
||||
|
||||
/*@+nullstate@ */
|
||||
/*@+mustfreefresh@ */
|
||||
|
||||
|
||||
/*
|
||||
* Set the process title visible to ps(1), by overwriting argv[0] with the
|
||||
* given printf() format string.
|
||||
*/
|
||||
void setproctitle(const char *format, ...)
|
||||
{
|
||||
char title[1024]; /* flawfinder: ignore */
|
||||
size_t length;
|
||||
va_list ap;
|
||||
|
||||
/* flawfinder - buffer is zeroed and users of it are bounded. */
|
||||
|
||||
if (NULL == base_argv)
|
||||
return;
|
||||
|
||||
memset(title, 0, sizeof(title));
|
||||
|
||||
va_start(ap, format);
|
||||
(void) vsnprintf(title, sizeof(title) - 1, format, ap); /* flawfinder: ignore */
|
||||
va_end(ap);
|
||||
|
||||
/*
|
||||
* flawfinder - the format is explicitly caller-supplied. Callers
|
||||
* of this function are all passing fixed format strings and not
|
||||
* user-supplied formats.
|
||||
*/
|
||||
|
||||
length = strlen(title); /* flawfinder: ignore */
|
||||
/* flawfinder - we left a byte at the end to force null-termination. */
|
||||
|
||||
if (length > space_available - 2)
|
||||
length = space_available - 2;
|
||||
|
||||
(void) pv_snprintf(base_argv[0], space_available, "%s -- %s", PACKAGE_NAME, title);
|
||||
if (space_available > length)
|
||||
memset(base_argv[0] + length, 0, space_available - length);
|
||||
}
|
||||
|
||||
#endif
|
||||
+137
-102
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Signal handling functions.
|
||||
*
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2024 Andrew Wood
|
||||
*
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
@@ -27,8 +27,13 @@ void pv_crs_needreinit(pvstate_t);
|
||||
|
||||
/*
|
||||
* Ensure that terminal attribute TOSTOP is set. If we have to set it,
|
||||
* record that fact by setting the state boolean "pv_tty_tostop_added" to
|
||||
* true, so that in pv_sig_fini() we can turn it back off again.
|
||||
* record that fact by setting "clear_tty_tostop_on_exit" to 1, so that in
|
||||
* pv_sig_fini() we can turn it back off again.
|
||||
*
|
||||
* In "-c" mode with IPC, then if we have to set TOSTOP, we also tell the
|
||||
* other PV instances about it via the shared "tty_tostop_added" flag, so
|
||||
* those instances can set their own on-exit flag, meaning that if any of
|
||||
* the PV instances set it, the last one to exit will clear it.
|
||||
*/
|
||||
static void pv_sig_ensure_tty_tostop()
|
||||
{
|
||||
@@ -37,71 +42,72 @@ static void pv_sig_ensure_tty_tostop()
|
||||
if (NULL == pv_sig_state)
|
||||
return;
|
||||
|
||||
/* Can't look at terminal flags if backgrounded. */
|
||||
if (1 == pv_sig_state->flag.suspend_stderr)
|
||||
return;
|
||||
|
||||
if (0 != tcgetattr(STDERR_FILENO, &terminal_attributes)) {
|
||||
debug("%s: %s", "failed to read terminal attributes", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Can't set terminal flags if backgrounded. */
|
||||
if (1 == pv_sig_state->flag.suspend_stderr)
|
||||
return;
|
||||
|
||||
if (0 == (terminal_attributes.c_lflag & TOSTOP)) {
|
||||
terminal_attributes.c_lflag |= TOSTOP;
|
||||
if (0 == tcsetattr(STDERR_FILENO, TCSANOW, &terminal_attributes)) {
|
||||
pv_sig_state->signal.pv_tty_tostop_added = true;
|
||||
pv_sig_state->flag.clear_tty_tostop_on_exit = 1;
|
||||
debug("%s", "set terminal TOSTOP attribute");
|
||||
#if HAVE_IPC
|
||||
/*
|
||||
* In "-c" mode with IPC, make all "pv -c" instances
|
||||
* aware that we set TOSTOP, so the last one can
|
||||
* clear it on exit.
|
||||
*/
|
||||
if (pv_sig_state->control.cursor && (NULL != pv_sig_state->cursor.shared)
|
||||
&& (!pv_sig_state->cursor.noipc)) {
|
||||
pv_sig_state->cursor.shared->tty_tostop_added = true;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
debug("%s: %s", "failed to set terminal TOSTOP attribute", strerror(errno));
|
||||
}
|
||||
#if HAVE_IPC
|
||||
/*
|
||||
* In "-c" mode with IPC, make all "pv -c" instances aware
|
||||
* that we set TOSTOP, so the last one can clear it on exit.
|
||||
*/
|
||||
if (pv_sig_state->control.cursor && (NULL != pv_sig_state->cursor.shared)
|
||||
&& (!pv_sig_state->cursor.noipc)) {
|
||||
pv_sig_state->cursor.shared->tty_tostop_added = true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle SIGTTOU (tty output for background process) by redirecting stderr
|
||||
* to /dev/null, so that we can be stopped and backgrounded without messing
|
||||
* up the terminal. We store the old stderr file descriptor so that on a
|
||||
* subsequent SIGCONT we can try writing to the terminal again, in case we
|
||||
* get backgrounded and later get foregrounded again.
|
||||
* Handle SIGTTOU (tty output for background process) by setting the flag to
|
||||
* suspend writes to stderr, so that we can be stopped and backgrounded
|
||||
* without messing up the terminal. On a subsequent SIGCONT we will try
|
||||
* writing to the terminal again, in case we get backgrounded and later get
|
||||
* foregrounded again.
|
||||
*
|
||||
* When we get backgrounded and cause a SIGTTOU, the rest of the pipeline
|
||||
* gets stopped too, so transfers involving pipelines need us to send a
|
||||
* SIGCONT to the rest of the process group here, otherwise backgrounding
|
||||
* stops transfers involving pipes.
|
||||
*/
|
||||
static void pv_sig_ttou( /*@unused@ */ __attribute__((unused))
|
||||
int s)
|
||||
{
|
||||
int fd;
|
||||
|
||||
if (NULL == pv_sig_state)
|
||||
return;
|
||||
|
||||
fd = open("/dev/null", O_RDWR); /* flawfinder: ignore */
|
||||
if (fd < 0) {
|
||||
debug("%s: %s", "failed to open /dev/null", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* flawfinder rationale: not checking for symlinks because this is
|
||||
* explicitly a device file under /dev so we assume it is safe to
|
||||
* open.
|
||||
*
|
||||
* TODO: look at just preventing stderr output instead of writing to
|
||||
* stderr while backgrounded.
|
||||
*/
|
||||
|
||||
if (-1 == pv_sig_state->signal.old_stderr)
|
||||
pv_sig_state->signal.old_stderr = dup(STDERR_FILENO);
|
||||
|
||||
if (dup2(fd, STDERR_FILENO) < 0) {
|
||||
debug("%s: %s", "failed to replace stderr", strerror(errno));
|
||||
}
|
||||
|
||||
if (0 != close(fd)) {
|
||||
debug("%s: %s", "failed to close /dev/null", strerror(errno));
|
||||
if (1 != pv_sig_state->flag.suspend_stderr) {
|
||||
debug("%s", "SIGTTOU - suspending stderr");
|
||||
pv_sig_state->flag.suspend_stderr = 1;
|
||||
/* Also tell the SIGCONT handler to do nothing next time. */
|
||||
pv_sig_state->flag.skip_next_sigcont++;
|
||||
/* Raise an immediate SIGCONT to bring the rest of the pipeline back up. */
|
||||
/*@-unrecog@ *//* splint doesn't know about killpg() */
|
||||
if (0 != killpg(getpgrp(), SIGCONT)) {
|
||||
debug("%s: %s", "killpg", strerror(errno));
|
||||
}
|
||||
/*@+unrecog@ */
|
||||
} else {
|
||||
debug("%s", "SIGTTOU - but stderr was already suspended");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,7 +131,7 @@ static void pv_sig_tstp( /*@unused@ */ __attribute__((unused))
|
||||
/*
|
||||
* Handle SIGCONT (continue if stopped) by adding the elapsed time since the
|
||||
* last SIGTSTP to the elapsed time offset, and by trying to write to the
|
||||
* terminal again (by replacing the /dev/null stderr with the old stderr).
|
||||
* terminal again.
|
||||
*/
|
||||
static void pv_sig_cont( /*@unused@ */ __attribute__((unused))
|
||||
int s)
|
||||
@@ -136,6 +142,18 @@ static void pv_sig_cont( /*@unused@ */ __attribute__((unused))
|
||||
if (NULL == pv_sig_state)
|
||||
return;
|
||||
|
||||
if (pv_sig_state->flag.skip_next_sigcont > 0) {
|
||||
debug("%s: %d", "SIGCONT received but ignored - current value of skip_next_sigcont",
|
||||
pv_sig_state->flag.skip_next_sigcont);
|
||||
pv_sig_state->flag.skip_next_sigcont--;
|
||||
return;
|
||||
} else if (pv_sig_state->flag.skip_next_sigcont < 0) {
|
||||
pv_sig_state->flag.skip_next_sigcont = 0;
|
||||
debug("%s", "skip_next_sigcont underrun cleared");
|
||||
}
|
||||
|
||||
debug("%s: %d", "SIGCONT received - current value of suspend_stderr", pv_sig_state->flag.suspend_stderr);
|
||||
|
||||
pv_sig_state->flag.terminal_resized = 1;
|
||||
|
||||
/*
|
||||
@@ -161,23 +179,24 @@ static void pv_sig_cont( /*@unused@ */ __attribute__((unused))
|
||||
}
|
||||
|
||||
/*
|
||||
* Restore the old stderr, if we had replaced it.
|
||||
* Try resuming our use of stderr, if we had suspended it, but only
|
||||
* if we're now in the foreground.
|
||||
*/
|
||||
if (pv_sig_state->signal.old_stderr != -1) {
|
||||
if (dup2(pv_sig_state->signal.old_stderr, STDERR_FILENO) < 0) {
|
||||
debug("%s: %s", "failed to restore old stderr", strerror(errno));
|
||||
if (1 == pv_sig_state->flag.suspend_stderr) {
|
||||
if (pv_in_foreground()) {
|
||||
debug("%s", "SIGCONT - resuming stderr");
|
||||
pv_sig_state->flag.suspend_stderr = 0;
|
||||
} else {
|
||||
debug("%s", "SIGCONT but still in background - not resuming stderr");
|
||||
}
|
||||
if (0 != close(pv_sig_state->signal.old_stderr)) {
|
||||
debug("%s: %s", "failed to close duplicate old stderr", strerror(errno));
|
||||
}
|
||||
pv_sig_state->signal.old_stderr = -1;
|
||||
}
|
||||
|
||||
pv_sig_ensure_tty_tostop();
|
||||
|
||||
if (0 == pv_sig_state->flag.suspend_stderr) {
|
||||
pv_sig_ensure_tty_tostop();
|
||||
#ifdef HAVE_IPC
|
||||
pv_crs_needreinit(pv_sig_state);
|
||||
pv_crs_needreinit(pv_sig_state);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -207,7 +226,7 @@ static void pv_sig_term( /*@unused@ */ __attribute__((unused))
|
||||
}
|
||||
|
||||
|
||||
#ifdef SA_SIGINFO
|
||||
#ifdef SIGINFO_PROVIDES_PID
|
||||
/*
|
||||
* Handle a SIGUSR2 by setting a flag to say we received it, after recording
|
||||
* the sending PID.
|
||||
@@ -220,8 +239,8 @@ static void pv_sig_usr2( /*@unused@ */ __attribute__((unused))
|
||||
return;
|
||||
if (NULL == info)
|
||||
return;
|
||||
pv_sig_state->signal.rxusr2 = 1;
|
||||
pv_sig_state->signal.sender = info->si_pid;
|
||||
pv_sig_state->signal.rxusr2 = 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -244,6 +263,22 @@ bool pv_sigusr2_received(pvstate_t state, pid_t * pid)
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Handle alarm signals by doing nothing.
|
||||
*
|
||||
* Note that we have to use a signal handler like this, instead of using
|
||||
* SIG_IGN, because if we ignore the signal entirely, it does nothing,
|
||||
* including not interrupting blocking write() calls - which is what we're
|
||||
* using alarm signals for in the first place.
|
||||
*/
|
||||
static void pv_sig_alrm( /*@unused@ */ __attribute__((unused))
|
||||
int s)
|
||||
{
|
||||
debug("%s", "SIGALRM received");
|
||||
/* Do nothing. */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialise signal handling.
|
||||
*/
|
||||
@@ -256,13 +291,13 @@ void pv_sig_init(pvstate_t state)
|
||||
/*
|
||||
* Note that wherever we use a "struct sigaction", we declare it
|
||||
* static and explicitly zero it before use, because it may contain
|
||||
* deeper structures (e.g. "sigset_t") which trigger splint
|
||||
* deeper structures (e.g. "sigset_t") which trigger splint
|
||||
* warnings about potential memory leaks.
|
||||
*/
|
||||
|
||||
pv_sig_state = state;
|
||||
|
||||
pv_sig_state->signal.old_stderr = -1;
|
||||
pv_sig_state->flag.suspend_stderr = 0;
|
||||
pv_elapsedtime_zero(&(pv_sig_state->signal.tstp_time));
|
||||
pv_elapsedtime_zero(&(pv_sig_state->signal.toffset));
|
||||
|
||||
@@ -273,8 +308,8 @@ void pv_sig_init(pvstate_t state)
|
||||
*/
|
||||
|
||||
/*
|
||||
* Ignore SIGPIPE, so we don't die if stdout is a pipe and the other
|
||||
* end closes unexpectedly.
|
||||
* Ignore SIGPIPE, so we don't die if the output is a pipe and the
|
||||
* other end closes unexpectedly.
|
||||
*/
|
||||
sa.sa_handler = SIG_IGN;
|
||||
(void) sigemptyset(&(sa.sa_mask));
|
||||
@@ -285,6 +320,7 @@ void pv_sig_init(pvstate_t state)
|
||||
* Handle SIGTTOU by continuing with output switched off, so that we
|
||||
* can be stopped and backgrounded without messing up the terminal.
|
||||
*/
|
||||
pv_sig_state->flag.skip_next_sigcont = 0;
|
||||
sa.sa_handler = pv_sig_ttou;
|
||||
(void) sigemptyset(&(sa.sa_mask));
|
||||
sa.sa_flags = 0;
|
||||
@@ -339,7 +375,7 @@ void pv_sig_init(pvstate_t state)
|
||||
sa.sa_flags = 0;
|
||||
(void) sigaction(SIGTERM, &sa, &(pv_sig_state->signal.old_sigterm));
|
||||
|
||||
#ifdef SA_SIGINFO
|
||||
#ifdef SIGINFO_PROVIDES_PID
|
||||
/*
|
||||
* Handle SIGUSR2 by setting a flag to say the signal has been
|
||||
* received, and storing the sending process's PID.
|
||||
@@ -360,6 +396,15 @@ void pv_sig_init(pvstate_t state)
|
||||
* while backgrounded (see the SIGTTOU handler above).
|
||||
*/
|
||||
pv_sig_ensure_tty_tostop();
|
||||
|
||||
/*
|
||||
* Handle SIGALRM by doing nothing, so we can use alarms or interval
|
||||
* timers to interrupt blocking writes (returning EINTR).
|
||||
*/
|
||||
sa.sa_handler = pv_sig_alrm;
|
||||
(void) sigemptyset(&(sa.sa_mask));
|
||||
sa.sa_flags = 0;
|
||||
(void) sigaction(SIGALRM, &sa, &(pv_sig_state->signal.old_sigalrm));
|
||||
}
|
||||
|
||||
|
||||
@@ -386,11 +431,12 @@ void pv_sig_fini( /*@unused@ */ __attribute__((unused)) pvstate_t state)
|
||||
(void) sigaction(SIGINT, &(pv_sig_state->signal.old_sigint), NULL);
|
||||
(void) sigaction(SIGHUP, &(pv_sig_state->signal.old_sighup), NULL);
|
||||
(void) sigaction(SIGTERM, &(pv_sig_state->signal.old_sigterm), NULL);
|
||||
#ifdef SA_SIGINFO
|
||||
#ifdef SIGINFO_PROVIDES_PID
|
||||
(void) sigaction(SIGUSR2, &(pv_sig_state->signal.old_sigusr2), NULL);
|
||||
#endif
|
||||
(void) sigaction(SIGALRM, &(pv_sig_state->signal.old_sigalrm), NULL);
|
||||
|
||||
need_to_clear_tostop = pv_sig_state->signal.pv_tty_tostop_added;
|
||||
need_to_clear_tostop = (1 == pv_sig_state->flag.clear_tty_tostop_on_exit) ? true : false;
|
||||
|
||||
if (pv_sig_state->control.cursor) {
|
||||
#ifdef HAVE_IPC
|
||||
@@ -431,7 +477,7 @@ void pv_sig_fini( /*@unused@ */ __attribute__((unused)) pvstate_t state)
|
||||
}
|
||||
}
|
||||
|
||||
pv_sig_state->signal.pv_tty_tostop_added = false;
|
||||
pv_sig_state->flag.clear_tty_tostop_on_exit = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -441,19 +487,17 @@ void pv_sig_fini( /*@unused@ */ __attribute__((unused)) pvstate_t state)
|
||||
*/
|
||||
void pv_sig_nopause(void)
|
||||
{
|
||||
static struct sigaction sa;
|
||||
sigset_t signal_set, signal_oldset;
|
||||
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
debug("%s", "blocking SIGTSTP, SIGCONT");
|
||||
|
||||
sa.sa_handler = SIG_IGN;
|
||||
(void) sigemptyset(&(sa.sa_mask));
|
||||
sa.sa_flags = 0;
|
||||
(void) sigaction(SIGTSTP, &sa, NULL);
|
||||
(void) sigemptyset(&signal_set);
|
||||
(void) sigaddset(&signal_set, SIGTSTP);
|
||||
(void) sigaddset(&signal_set, SIGCONT);
|
||||
|
||||
sa.sa_handler = SIG_DFL;
|
||||
(void) sigemptyset(&(sa.sa_mask));
|
||||
sa.sa_flags = 0;
|
||||
(void) sigaction(SIGCONT, &sa, NULL);
|
||||
if (0 != sigprocmask(SIG_BLOCK, &signal_set, &signal_oldset)) {
|
||||
debug("%s: %s", "failed to set signal mask", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -462,27 +506,24 @@ void pv_sig_nopause(void)
|
||||
*/
|
||||
void pv_sig_allowpause(void)
|
||||
{
|
||||
static struct sigaction sa;
|
||||
sigset_t signal_set, signal_oldset;
|
||||
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
debug("%s", "unblocking SIGTSTP, SIGCONT");
|
||||
|
||||
sa.sa_handler = pv_sig_tstp;
|
||||
(void) sigemptyset(&(sa.sa_mask));
|
||||
sa.sa_flags = 0;
|
||||
(void) sigaction(SIGTSTP, &sa, NULL);
|
||||
(void) sigemptyset(&signal_set);
|
||||
(void) sigaddset(&signal_set, SIGTSTP);
|
||||
(void) sigaddset(&signal_set, SIGCONT);
|
||||
|
||||
sa.sa_handler = pv_sig_cont;
|
||||
(void) sigemptyset(&(sa.sa_mask));
|
||||
sa.sa_flags = 0;
|
||||
(void) sigaction(SIGCONT, &sa, NULL);
|
||||
if (0 != sigprocmask(SIG_UNBLOCK, &signal_set, &signal_oldset)) {
|
||||
debug("%s: %s", "failed to set signal mask", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* If we have redirected stderr to /dev/null, check every second or so to
|
||||
* see whether we can write to the terminal again - this is so that if we
|
||||
* get backgrounded, then foregrounded again, we start writing to the
|
||||
* terminal again.
|
||||
* If we have suspended stderr, check every second or so to see whether we
|
||||
* can write to the terminal again - this is so that if we get backgrounded,
|
||||
* then foregrounded again, we start writing to the terminal again.
|
||||
*/
|
||||
void pv_sig_checkbg(void)
|
||||
{
|
||||
@@ -496,23 +537,17 @@ void pv_sig_checkbg(void)
|
||||
|
||||
next_check = time(NULL) + 1;
|
||||
|
||||
if (-1 == pv_sig_state->signal.old_stderr)
|
||||
if (0 == pv_sig_state->flag.suspend_stderr)
|
||||
return;
|
||||
|
||||
if (dup2(pv_sig_state->signal.old_stderr, STDERR_FILENO) < 0) {
|
||||
debug("%s: %s", "failed to restore old stderr", strerror(errno));
|
||||
}
|
||||
if (!pv_in_foreground())
|
||||
return;
|
||||
|
||||
if (0 != close(pv_sig_state->signal.old_stderr)) {
|
||||
debug("%s: %s", "failed to close duplicate old stderr", strerror(errno));
|
||||
}
|
||||
|
||||
pv_sig_state->signal.old_stderr = -1;
|
||||
debug("%s: %s", "pv_sig_checkbg", "attempting to resume stderr");
|
||||
pv_sig_state->flag.suspend_stderr = 0;
|
||||
|
||||
pv_sig_ensure_tty_tostop();
|
||||
#ifdef HAVE_IPC
|
||||
pv_crs_needreinit(pv_sig_state);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
||||
+207
-23
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* State management functions.
|
||||
*
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2024 Andrew Wood
|
||||
*
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
@@ -10,22 +10,26 @@
|
||||
#include "pv.h"
|
||||
#include "pv-internal.h"
|
||||
|
||||
/* We do not set this because it breaks "dd" - see below. */
|
||||
/* #undef MAKE_OUTPUT_NONBLOCKING */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
|
||||
/* alloc / realloc history buffer */
|
||||
static void pv_alloc_history(pvstate_t state)
|
||||
{
|
||||
if (NULL != state->display.history)
|
||||
free(state->display.history);
|
||||
state->display.history = NULL;
|
||||
if (NULL != state->calc.history)
|
||||
free(state->calc.history);
|
||||
state->calc.history = NULL;
|
||||
|
||||
state->display.history = calloc((size_t) (state->display.history_len), sizeof(state->display.history[0]));
|
||||
if (NULL == state->display.history) {
|
||||
state->calc.history = calloc((size_t) (state->calc.history_len), sizeof(state->calc.history[0]));
|
||||
if (NULL == state->calc.history) {
|
||||
/*@-mustfreefresh@ */
|
||||
/*
|
||||
* splint note: the gettext calls made by _() cause memory
|
||||
@@ -38,10 +42,69 @@ static void pv_alloc_history(pvstate_t state)
|
||||
return;
|
||||
}
|
||||
|
||||
state->display.history_first = state->display.history_last = 0;
|
||||
state->display.history[0].elapsed_sec = 0.0; /* to be safe, memset() not recommended for doubles */
|
||||
state->calc.history_first = state->calc.history_last = 0;
|
||||
state->calc.history[0].elapsed_sec = 0.0; /* to be safe, memset() not recommended for doubles */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Clear the calculated parts of a state structure.
|
||||
*/
|
||||
void pv_state_reset(pvstate_t state)
|
||||
{
|
||||
if (NULL == state)
|
||||
return;
|
||||
|
||||
state->flag.reparse_display = 1;
|
||||
state->status.current_input_file = -1;
|
||||
|
||||
state->display.initial_offset = 0;
|
||||
state->display.display_visible = false;
|
||||
|
||||
state->extra_display.initial_offset = 0;
|
||||
state->extra_display.display_visible = false;
|
||||
|
||||
/*
|
||||
* Explicitly set important floating point values to 0, as memset()
|
||||
* is not recommended for this.
|
||||
*/
|
||||
state->calc.transfer_rate = 0.0;
|
||||
state->calc.average_rate = 0.0;
|
||||
state->calc.prev_elapsed_sec = 0.0;
|
||||
state->calc.prev_rate = 0.0;
|
||||
state->calc.prev_trans = 0.0;
|
||||
state->calc.current_avg_rate = 0.0;
|
||||
state->calc.rate_min = 0.0;
|
||||
state->calc.rate_max = 0.0;
|
||||
state->calc.rate_sum = 0.0;
|
||||
state->calc.ratesquared_sum = 0.0;
|
||||
state->calc.measurements_taken = 0;
|
||||
state->calc.prev_transferred = 0;
|
||||
state->calc.percentage = 0;
|
||||
state->calc.history_first = state->calc.history_last = 0;
|
||||
if (NULL != state->calc.history) {
|
||||
state->calc.history[0].elapsed_sec = 0.0;
|
||||
}
|
||||
|
||||
state->transfer.elapsed_seconds = 0.0;
|
||||
state->transfer.read_position = 0;
|
||||
state->transfer.write_position = 0;
|
||||
state->transfer.to_write = 0;
|
||||
state->transfer.written = 0;
|
||||
state->transfer.total_written = 0;
|
||||
state->transfer.written_but_not_consumed = 0;
|
||||
state->transfer.read_errors_in_a_row = 0;
|
||||
state->transfer.last_read_skip_fd = 0;
|
||||
#ifdef HAVE_SPLICE
|
||||
state->transfer.splice_failed_fd = -1;
|
||||
#endif /* HAVE_SPLICE */
|
||||
|
||||
state->transfer.line_positions_length = 0;
|
||||
state->transfer.line_positions_head = 0;
|
||||
state->transfer.last_output_position = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Create a new state structure, and return it, or 0 (NULL) on error.
|
||||
*/
|
||||
@@ -67,18 +130,14 @@ pvstate_t pv_state_alloc(const char *program_name)
|
||||
|
||||
state->control.watch_pid = 0;
|
||||
state->control.watch_fd = -1;
|
||||
state->control.output_fd = -1;
|
||||
#ifdef HAVE_IPC
|
||||
state->cursor.shmid = -1;
|
||||
state->cursor.pvcount = 1;
|
||||
#endif /* HAVE_IPC */
|
||||
state->cursor.lock_fd = -1;
|
||||
|
||||
state->flag.reparse_display = 1;
|
||||
state->status.current_input_file = -1;
|
||||
#ifdef HAVE_SPLICE
|
||||
state->transfer.splice_failed_fd = -1;
|
||||
#endif /* HAVE_SPLICE */
|
||||
state->display.display_visible = false;
|
||||
pv_state_reset(state);
|
||||
|
||||
/*
|
||||
* Get the current working directory, if possible, as a base for
|
||||
@@ -106,6 +165,26 @@ void pv_state_free(pvstate_t state)
|
||||
if (0 == state)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Close the output file first, so we can report any errors while we
|
||||
* still know the program name and output filename.
|
||||
*/
|
||||
if (state->control.output_fd >= 0) {
|
||||
if (STDOUT_FILENO != state->control.output_fd) {
|
||||
if (close(state->control.output_fd) < 0) {
|
||||
fprintf(stderr, "%s: %s: %s\n", state->status.program_name,
|
||||
NULL == state->control.output_name ? "(null)" : state->control.output_name,
|
||||
strerror(errno));
|
||||
}
|
||||
}
|
||||
state->control.output_fd = -1;
|
||||
}
|
||||
|
||||
if (NULL != state->control.output_name) {
|
||||
free(state->control.output_name);
|
||||
state->control.output_name = NULL;
|
||||
}
|
||||
|
||||
if (NULL != state->status.program_name)
|
||||
free(state->status.program_name);
|
||||
state->status.program_name = NULL;
|
||||
@@ -114,6 +193,10 @@ void pv_state_free(pvstate_t state)
|
||||
free(state->display.display_buffer);
|
||||
state->display.display_buffer = NULL;
|
||||
|
||||
if (NULL != state->extra_display.display_buffer)
|
||||
free(state->extra_display.display_buffer);
|
||||
state->extra_display.display_buffer = NULL;
|
||||
|
||||
if (NULL != state->control.name) {
|
||||
free(state->control.name);
|
||||
state->control.name = NULL;
|
||||
@@ -124,6 +207,11 @@ void pv_state_free(pvstate_t state)
|
||||
state->control.format_string = NULL;
|
||||
}
|
||||
|
||||
if (NULL != state->control.extra_format_string) {
|
||||
free(state->control.extra_format_string);
|
||||
state->control.extra_format_string = NULL;
|
||||
}
|
||||
|
||||
/*@-keeptrans@ */
|
||||
if (NULL != state->transfer.transfer_buffer)
|
||||
free(state->transfer.transfer_buffer);
|
||||
@@ -131,9 +219,13 @@ void pv_state_free(pvstate_t state)
|
||||
/*@+keeptrans@ */
|
||||
/* splint - explicitly freeing this structure, so free() here is OK. */
|
||||
|
||||
if (NULL != state->display.history)
|
||||
free(state->display.history);
|
||||
state->display.history = NULL;
|
||||
if (NULL != state->transfer.line_positions)
|
||||
free(state->transfer.line_positions);
|
||||
state->transfer.line_positions = NULL;
|
||||
|
||||
if (NULL != state->calc.history)
|
||||
free(state->calc.history);
|
||||
state->calc.history = NULL;
|
||||
|
||||
if (NULL != state->files.filename) {
|
||||
unsigned int file_idx;
|
||||
@@ -209,6 +301,11 @@ void pv_state_cursor_set(pvstate_t state, bool val)
|
||||
state->control.cursor = val;
|
||||
}
|
||||
|
||||
void pv_state_show_stats_set(pvstate_t state, bool val)
|
||||
{
|
||||
state->control.show_stats = val;
|
||||
}
|
||||
|
||||
void pv_state_numeric_set(pvstate_t state, bool val)
|
||||
{
|
||||
state->control.numeric = val;
|
||||
@@ -224,6 +321,11 @@ void pv_state_delay_start_set(pvstate_t state, double val)
|
||||
state->control.delay_start = val;
|
||||
}
|
||||
|
||||
void pv_state_rate_gauge_set(pvstate_t state, bool val)
|
||||
{
|
||||
state->control.rate_gauge = val;
|
||||
}
|
||||
|
||||
void pv_state_linemode_set(pvstate_t state, bool val)
|
||||
{
|
||||
state->control.linemode = val;
|
||||
@@ -234,6 +336,11 @@ void pv_state_bits_set(pvstate_t state, bool bits)
|
||||
state->control.bits = bits;
|
||||
}
|
||||
|
||||
void pv_state_decimal_units_set(pvstate_t state, bool decimal_units)
|
||||
{
|
||||
state->control.decimal_units = decimal_units;
|
||||
}
|
||||
|
||||
void pv_state_null_terminated_lines_set(pvstate_t state, bool val)
|
||||
{
|
||||
state->control.null_terminated_lines = val;
|
||||
@@ -332,6 +439,57 @@ void pv_state_format_string_set(pvstate_t state, /*@null@ */ const char *val)
|
||||
state->control.format_string = pv_strdup(val);
|
||||
}
|
||||
|
||||
void pv_state_extra_display_set(pvstate_t state, /*@null@ */ const char *val)
|
||||
{
|
||||
const char *word_start;
|
||||
size_t offset;
|
||||
|
||||
if (NULL != state->control.extra_format_string) {
|
||||
free(state->control.extra_format_string);
|
||||
state->control.extra_format_string = NULL;
|
||||
}
|
||||
|
||||
state->control.extra_displays = 0;
|
||||
if (NULL == val)
|
||||
return;
|
||||
|
||||
word_start = val;
|
||||
while (NULL != word_start && '\0' != word_start[0]) {
|
||||
offset = 0;
|
||||
while ('\0' != word_start[offset] && ',' != word_start[offset] && ':' != word_start[offset])
|
||||
offset++;
|
||||
if (((11 == offset) && (0 == strncmp(word_start, "windowtitle", 11)))
|
||||
|| ((6 == offset) && (0 == strncmp(word_start, "window", 6)))
|
||||
) {
|
||||
debug("%s", "enabling windowtitle");
|
||||
state->control.extra_displays |= PV_DISPLAY_WINDOWTITLE;
|
||||
} else if (((12 == offset) && (0 == strncmp(word_start, "processtitle", 12)))
|
||||
|| ((9 == offset) && (0 == strncmp(word_start, "proctitle", 9)))
|
||||
|| ((7 == offset) && (0 == strncmp(word_start, "process", 7)))
|
||||
|| ((4 == offset) && (0 == strncmp(word_start, "proc", 4)))
|
||||
) {
|
||||
debug("%s", "enabling processtitle");
|
||||
state->control.extra_displays |= PV_DISPLAY_PROCESSTITLE;
|
||||
}
|
||||
switch (word_start[offset]) {
|
||||
case ',':
|
||||
offset++;
|
||||
break;
|
||||
case ':':
|
||||
offset++;
|
||||
debug("%s: [%s]", "setting extra_format_string", word_start + offset);
|
||||
state->control.extra_format_string = pv_strdup(word_start + offset);
|
||||
word_start = NULL;
|
||||
break;
|
||||
default:
|
||||
word_start = NULL;
|
||||
break;
|
||||
}
|
||||
if (NULL != word_start)
|
||||
word_start += offset;
|
||||
}
|
||||
}
|
||||
|
||||
void pv_state_watch_pid_set(pvstate_t state, pid_t val)
|
||||
{
|
||||
state->control.watch_pid = val;
|
||||
@@ -342,17 +500,45 @@ void pv_state_watch_fd_set(pvstate_t state, int val)
|
||||
state->control.watch_fd = val;
|
||||
}
|
||||
|
||||
void pv_state_output_set(pvstate_t state, int fd, const char *name)
|
||||
{
|
||||
/*
|
||||
* Close any previous output file first, so we can report any errors
|
||||
* before we store the new output filename.
|
||||
*/
|
||||
if (state->control.output_fd >= 0 && state->control.output_fd != STDOUT_FILENO) {
|
||||
if (close(state->control.output_fd) < 0) {
|
||||
fprintf(stderr, "%s: %s: %s\n", state->status.program_name,
|
||||
NULL == state->control.output_name ? "(null)" : state->control.output_name,
|
||||
strerror(errno));
|
||||
}
|
||||
}
|
||||
if (NULL != state->control.output_name)
|
||||
free(state->control.output_name);
|
||||
state->control.output_fd = fd;
|
||||
state->control.output_name = pv_strdup(name);
|
||||
#ifdef MAKE_OUTPUT_NONBLOCKING
|
||||
/*
|
||||
* Try and make the output use non-blocking I/O.
|
||||
*
|
||||
* Note that this can cause problems with (broken) applications
|
||||
* such as dd when used in a pipeline.
|
||||
*/
|
||||
fcntl(state->control.output_fd, F_SETFL, O_NONBLOCK | fcntl(state->control.output_fd, F_GETFL));
|
||||
#endif /* MAKE_OUTPUT_NONBLOCKING */
|
||||
}
|
||||
|
||||
void pv_state_average_rate_window_set(pvstate_t state, unsigned int val)
|
||||
{
|
||||
if (val < 1)
|
||||
val = 1;
|
||||
state->control.average_rate_window = val;
|
||||
if (val >= 20) {
|
||||
state->display.history_len = (size_t) (val / 5 + 1);
|
||||
state->display.history_interval = 5;
|
||||
state->calc.history_len = (size_t) (val / 5 + 1);
|
||||
state->control.history_interval = 5;
|
||||
} else {
|
||||
state->display.history_len = (size_t) (val + 1);
|
||||
state->display.history_interval = 1;
|
||||
state->calc.history_len = (size_t) (val + 1);
|
||||
state->control.history_interval = 1;
|
||||
}
|
||||
pv_alloc_history(state);
|
||||
}
|
||||
@@ -404,5 +590,3 @@ void pv_state_inputfiles(pvstate_t state, unsigned int input_file_count, const c
|
||||
|
||||
/*@+nullstate@*/
|
||||
/* splint: see unqualifiedtrans note by free() above. */
|
||||
|
||||
/* EOF */
|
||||
|
||||
+1
-3
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Functions for portably managing strings.
|
||||
*
|
||||
* Copyright 2023 Andrew Wood
|
||||
* Copyright 2023-2024 Andrew Wood
|
||||
*
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
@@ -179,5 +179,3 @@ void *pv_memrchr(const void *buffer, int match, size_t length)
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
||||
+155
-55
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Functions for transferring data between file descriptors.
|
||||
*
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2024 Andrew Wood
|
||||
*
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
@@ -156,8 +156,8 @@ static ssize_t pv__transfer_read_repeated(int fd, void *buf, size_t count)
|
||||
elapsed_seconds = pv_elapsedtime_seconds(&transfer_elapsed);
|
||||
|
||||
if (elapsed_seconds > TRANSFER_READ_TIMEOUT) {
|
||||
debug("%s %d: %s (%lf %s)", "fd", fd,
|
||||
"stopping read - timer expired", elapsed_seconds, "sec elapsed");
|
||||
debug("%s %d: %s (%f %s)", "fd", fd,
|
||||
"stopping read - timer expired", (double) elapsed_seconds, "sec elapsed");
|
||||
return total_read;
|
||||
}
|
||||
|
||||
@@ -181,6 +181,12 @@ static ssize_t pv__transfer_read_repeated(int fd, void *buf, size_t count)
|
||||
* see if we can write any more, and keep trying, to make sure we empty the
|
||||
* buffer as much as we can.
|
||||
*
|
||||
* While this is called after a successful write-possible select(), write() is
|
||||
* not guaranteed to succeed for _all_ sizes; we may end up returning 0 if this
|
||||
* occurs. (The first write() may return -1 / EINTR if the consumer doesn't
|
||||
* read any data before our timeout and the buffer of whatever stdout is is
|
||||
* near-full.) (see https://codeberg.org/a-j-wood/pv/pulls/93)
|
||||
*
|
||||
* If "sync_after_write" is true, we call fdatasync() after each write() (or
|
||||
* fsync() if _POSIX_SYNCHRONIZED_IO is not > 0).
|
||||
*
|
||||
@@ -231,8 +237,8 @@ static ssize_t pv__transfer_write_repeated(int fd, void *buf, size_t count, bool
|
||||
if ((EINTR == errno) || (EAGAIN == errno)) {
|
||||
/*
|
||||
* Interrupted by a signal - probably our
|
||||
* alarm() - so just return what we've
|
||||
* written so far.
|
||||
* alarm or interval timer - so just return
|
||||
* what we've written so far.
|
||||
*/
|
||||
return total_written;
|
||||
} else {
|
||||
@@ -259,16 +265,17 @@ static ssize_t pv__transfer_write_repeated(int fd, void *buf, size_t count, bool
|
||||
elapsed_seconds = pv_elapsedtime_seconds(&transfer_elapsed);
|
||||
|
||||
if (elapsed_seconds > TRANSFER_WRITE_TIMEOUT) {
|
||||
debug("%s %d: %s (%lf %s)", "fd", fd,
|
||||
"stopping write - timer expired", elapsed_seconds, "sec elapsed");
|
||||
debug("%s %d: %s (%f %s)", "fd", fd,
|
||||
"stopping write - timer expired", (double) elapsed_seconds, "sec elapsed");
|
||||
return total_written;
|
||||
}
|
||||
|
||||
/*
|
||||
* Running the select() here seems to make PV eat a lot of
|
||||
* CPU in some cases, so instead we just go round the loop
|
||||
* again and rely on our alarm() to interrupt us if we run
|
||||
* out of time - also on our elapsed time check.
|
||||
* again and rely on our alarm or interval timer to
|
||||
* interrupt us if we run out of time - also on our elapsed
|
||||
* time check.
|
||||
*/
|
||||
if (count > 0) {
|
||||
debug("%s %d: %s (%ld %s, %ld %s)", "fd", fd,
|
||||
@@ -344,7 +351,7 @@ static int pv__transfer_read(pvstate_t state, int fd, bool *eof_in, bool *eof_ou
|
||||
/*@-nullpass@ */
|
||||
/*@-type@ */
|
||||
/* splint doesn't know about splice */
|
||||
nread = splice(fd, NULL, STDOUT_FILENO, NULL, bytes_to_splice, SPLICE_F_MORE);
|
||||
nread = splice(fd, NULL, state->control.output_fd, NULL, bytes_to_splice, SPLICE_F_MORE);
|
||||
/*@+type@ */
|
||||
/*@+nullpass@ */
|
||||
|
||||
@@ -369,7 +376,7 @@ static int pv__transfer_read(pvstate_t state, int fd, bool *eof_in, bool *eof_ou
|
||||
* error, we cannot skip it, so set
|
||||
* "do_not_skip_errors".
|
||||
*/
|
||||
if ((fdatasync(STDOUT_FILENO) < 0)
|
||||
if ((fdatasync(state->control.output_fd) < 0)
|
||||
&& (EIO == errno)) {
|
||||
nread = -1;
|
||||
do_not_skip_errors = true;
|
||||
@@ -445,7 +452,7 @@ static int pv__transfer_read(pvstate_t state, int fd, bool *eof_in, bool *eof_ou
|
||||
* exit status, regardless of whether we're skipping errors, and
|
||||
* increment the error counter.
|
||||
*/
|
||||
state->status.exit_status |= 16;
|
||||
state->status.exit_status |= PV_ERROREXIT_TRANSFER;
|
||||
state->transfer.read_errors_in_a_row++;
|
||||
|
||||
/*
|
||||
@@ -611,13 +618,13 @@ static int pv__transfer_read(pvstate_t state, int fd, bool *eof_in, bool *eof_ou
|
||||
|
||||
|
||||
/*
|
||||
* Write state->transfer.to_write bytes of data from the transfer buffer to stdout.
|
||||
* Write state->transfer.to_write bytes of data from the transfer buffer to the output.
|
||||
* Returns zero if there was a transient error and we need to return 0 from
|
||||
* pv_transfer, otherwise returns 1.
|
||||
*
|
||||
* Updates state->transfer.write_position by moving it on by the number of bytes
|
||||
* written; adds the number of bytes written to state->transfer.written; sets
|
||||
* *eof_out to true, on stdout EOF, or when the write position catches up
|
||||
* *eof_out to true, on output EOF, or when the write position catches up
|
||||
* with the read position AND *eof_in is true (meaning we've reached the end
|
||||
* of data).
|
||||
*
|
||||
@@ -629,40 +636,88 @@ static int pv__transfer_read(pvstate_t state, int fd, bool *eof_in, bool *eof_ou
|
||||
static int pv__transfer_write(pvstate_t state, bool *eof_in, bool *eof_out, long *lineswritten)
|
||||
{
|
||||
ssize_t nwritten;
|
||||
int write_errno;
|
||||
|
||||
if (NULL == state->transfer.transfer_buffer) {
|
||||
pv_error(state, "%s", _("no transfer buffer allocated"));
|
||||
state->status.exit_status |= 64;
|
||||
state->status.exit_status |= PV_ERROREXIT_MEMORY;
|
||||
*eof_out = true;
|
||||
state->transfer.written = -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
nwritten = 0;
|
||||
write_errno = 0;
|
||||
|
||||
if (state->control.discard_input) {
|
||||
nwritten = state->transfer.to_write;
|
||||
} else if (state->transfer.to_write > 0) {
|
||||
if (signal(SIGALRM, SIG_IGN) == SIG_ERR) {
|
||||
pv_error(state, "%s: %s", _("failed to set alarm signal handler"), strerror(errno));
|
||||
} else {
|
||||
(void) alarm(1);
|
||||
|
||||
/*
|
||||
* Set an interval timer or an alarm to interrupt the write
|
||||
* with a signal if the write takes too long, so we can
|
||||
* continue producing progress information.
|
||||
*/
|
||||
#if HAVE_SETITIMER
|
||||
struct itimerval new_timer;
|
||||
|
||||
/*@-unrecog@ */
|
||||
/* splint doesn't know setitimer or ITIMER_REAL */
|
||||
memset(&new_timer, 0, sizeof(new_timer));
|
||||
new_timer.it_value.tv_sec = (time_t) (state->control.interval);
|
||||
new_timer.it_value.tv_usec = (suseconds_t) (((long) (state->control.interval * 1000000.0)) % 1000000);
|
||||
|
||||
/*
|
||||
* We have to set the interval so that the timer continues
|
||||
* to repeat while writes are attempted, especially as it's
|
||||
* possible that the initial timer run will expire
|
||||
* immediately if the period is less than 1 second.
|
||||
*/
|
||||
|
||||
new_timer.it_interval.tv_sec = new_timer.it_value.tv_sec;
|
||||
new_timer.it_interval.tv_usec = new_timer.it_value.tv_usec;
|
||||
|
||||
debug("%s: [%lds,%ldus]", "setting interval timer", (long) (new_timer.it_value.tv_sec),
|
||||
(long) (new_timer.it_value.tv_usec));
|
||||
|
||||
if (0 != setitimer(ITIMER_REAL, &new_timer, NULL)) {
|
||||
pv_error(state, "%s: %s", _("failed to set interval timer"), strerror(errno));
|
||||
}
|
||||
nwritten = pv__transfer_write_repeated(STDOUT_FILENO,
|
||||
|
||||
#else /* ! HAVE_SETITIMER */
|
||||
(void) alarm(1);
|
||||
debug("%s", "setting alarm");
|
||||
#endif /* HAVE_SETITIMER */
|
||||
debug("%s: %ld %s", "beginning write attempt", (long) (state->transfer.to_write), "bytes");
|
||||
nwritten = pv__transfer_write_repeated(state->control.output_fd,
|
||||
state->transfer.transfer_buffer +
|
||||
state->transfer.write_position,
|
||||
(size_t) (state->transfer.to_write),
|
||||
state->control.sync_after_write);
|
||||
if (nwritten < 0) {
|
||||
write_errno = (int) errno;
|
||||
debug("%s: %ld: %s", "bytes written", (long) nwritten, strerror(errno));
|
||||
} else {
|
||||
debug("%s: %ld", "bytes written", (long) nwritten);
|
||||
}
|
||||
#if HAVE_SETITIMER
|
||||
memset(&new_timer, 0, sizeof(new_timer));
|
||||
new_timer.it_interval.tv_sec = 0;
|
||||
new_timer.it_interval.tv_usec = 0;
|
||||
new_timer.it_value.tv_sec = 0;
|
||||
new_timer.it_value.tv_usec = 0;
|
||||
if (0 != setitimer(ITIMER_REAL, &new_timer, NULL)) {
|
||||
pv_error(state, "%s: %s", _("failed to clear interval timer"), strerror(errno));
|
||||
}
|
||||
|
||||
/*@+unrecog@ */
|
||||
#else /* ! HAVE_SETITIMER */
|
||||
debug("%s", "cancelling alarm");
|
||||
(void) alarm(0);
|
||||
#endif /* HAVE_SETITIMER */
|
||||
}
|
||||
|
||||
if (0 == nwritten) {
|
||||
/*
|
||||
* Write returned 0 - EOF on stdout.
|
||||
*/
|
||||
*eof_out = true;
|
||||
return 1;
|
||||
} else if (nwritten > 0) {
|
||||
if (nwritten > 0) {
|
||||
/*
|
||||
* Write returned >0 - data successfully written.
|
||||
*/
|
||||
@@ -671,6 +726,22 @@ static int pv__transfer_write(pvstate_t state, bool *eof_in, bool *eof_out, long
|
||||
char *ptr;
|
||||
long lines = 0;
|
||||
|
||||
/*
|
||||
* Line mode - look through what we've just written
|
||||
* to count how many lines there were.
|
||||
*/
|
||||
|
||||
/* Allocate buffer to remember line positions. */
|
||||
if (NULL == state->transfer.line_positions) {
|
||||
state->transfer.line_positions_capacity = MAX_LINE_POSITIONS;
|
||||
state->transfer.line_positions =
|
||||
calloc((size_t) (state->transfer.line_positions_capacity), sizeof(off_t));
|
||||
if (NULL == state->transfer.line_positions) {
|
||||
pv_error(state, "%s: %s", _("line position buffer allocation failed"),
|
||||
strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
if (state->control.null_terminated_lines) {
|
||||
separator = '\0';
|
||||
} else {
|
||||
@@ -680,9 +751,30 @@ static int pv__transfer_write(pvstate_t state, bool *eof_in, bool *eof_out, long
|
||||
ptr = (char *) (state->transfer.transfer_buffer + state->transfer.write_position - 1);
|
||||
for (ptr++;
|
||||
ptr - (char *) state->transfer.transfer_buffer - state->transfer.write_position <
|
||||
(size_t) nwritten; ptr++) {
|
||||
if (*ptr == separator)
|
||||
++lines;
|
||||
(size_t) nwritten; ptr++, state->transfer.last_output_position++) {
|
||||
if (*ptr != separator)
|
||||
continue;
|
||||
|
||||
/* Separator found - increment line count. */
|
||||
++lines;
|
||||
|
||||
if (NULL == state->transfer.line_positions)
|
||||
continue;
|
||||
|
||||
/* Store the position of the separator. */
|
||||
state->transfer.line_positions[state->transfer.line_positions_head] =
|
||||
state->transfer.last_output_position;
|
||||
state->transfer.line_positions_head++;
|
||||
|
||||
/* Circular buffer - wrap around. */
|
||||
if (state->transfer.line_positions_head >= state->transfer.line_positions_capacity) {
|
||||
state->transfer.line_positions_head = 0;
|
||||
}
|
||||
|
||||
/* Increment count of line positions, if below capacity. */
|
||||
if (state->transfer.line_positions_length < state->transfer.line_positions_capacity) {
|
||||
state->transfer.line_positions_length++;
|
||||
}
|
||||
}
|
||||
|
||||
*lineswritten += lines;
|
||||
@@ -748,15 +840,20 @@ static int pv__transfer_write(pvstate_t state, bool *eof_in, bool *eof_out, long
|
||||
}
|
||||
|
||||
/*
|
||||
* If we reach this point, nwritten<0, so there was an error.
|
||||
* If we reach this point, nwritten<=0, so there may be an error.
|
||||
*/
|
||||
|
||||
/*
|
||||
* If a write error occurred but it was EINTR or EAGAIN, just wait a
|
||||
* bit and then return zero, since this was a transient error.
|
||||
* If a write error occurred but it was EINTR or EAGAIN, or write(2)
|
||||
* blocked on first write such that nwritten == 0, just wait a bit and
|
||||
* then return zero, since this was a transient error.
|
||||
*/
|
||||
if ((EINTR == errno) || (EAGAIN == errno)) {
|
||||
debug("%s: %s", "transient write error - waiting briefly", strerror(errno));
|
||||
if ((0 == nwritten) || (EINTR == write_errno) || (EAGAIN == write_errno)) {
|
||||
if (0 == nwritten) {
|
||||
debug("%s", "attempted write blocked - waiting briefly");
|
||||
} else {
|
||||
debug("%s: %s", "transient write error - waiting briefly", strerror(write_errno));
|
||||
}
|
||||
(void) is_data_ready(-1, NULL, -1, NULL, 10000);
|
||||
return 0;
|
||||
}
|
||||
@@ -765,14 +862,15 @@ static int pv__transfer_write(pvstate_t state, bool *eof_in, bool *eof_out, long
|
||||
* SIGPIPE means we've finished. Don't output an error because it's
|
||||
* not really our error to report.
|
||||
*/
|
||||
if (EPIPE == errno) {
|
||||
if (EPIPE == write_errno) {
|
||||
*eof_in = true;
|
||||
*eof_out = true;
|
||||
state->flag.pipe_closed = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
pv_error(state, "%s: %s", _("write failed"), strerror(errno));
|
||||
state->status.exit_status |= 16;
|
||||
pv_error(state, "%s: %s", _("write failed"), strerror(write_errno));
|
||||
state->status.exit_status |= PV_ERROREXIT_TRANSFER;
|
||||
*eof_out = true;
|
||||
state->transfer.written = -1;
|
||||
|
||||
@@ -794,7 +892,7 @@ static int pv__transfer_write(pvstate_t state, bool *eof_in, bool *eof_out, long
|
||||
*/
|
||||
/*@null@*/
|
||||
/*@only@*/
|
||||
static char *pv__allocate_aligned_buffer(int fd, size_t target_size)
|
||||
static char *pv__allocate_aligned_buffer(int outfd, int infd, size_t target_size)
|
||||
{
|
||||
char *newptr;
|
||||
|
||||
@@ -802,8 +900,8 @@ static char *pv__allocate_aligned_buffer(int fd, size_t target_size)
|
||||
long input_alignment, output_alignment, min_alignment;
|
||||
long required_alignment;
|
||||
|
||||
input_alignment = fd >= 0 ? fpathconf(fd, _PC_REC_XFER_ALIGN) : -1;
|
||||
output_alignment = fpathconf(STDOUT_FILENO, _PC_REC_XFER_ALIGN);
|
||||
input_alignment = infd >= 0 ? fpathconf(infd, _PC_REC_XFER_ALIGN) : -1;
|
||||
output_alignment = fpathconf(outfd, _PC_REC_XFER_ALIGN);
|
||||
#if defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE)
|
||||
min_alignment = sysconf(_SC_PAGESIZE);
|
||||
#else /* ! defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE) */
|
||||
@@ -880,9 +978,12 @@ ssize_t pv_transfer(pvstate_t state, int fd, bool *eof_in, bool *eof_out, off_t
|
||||
}
|
||||
}
|
||||
if (!(*eof_out)) {
|
||||
if (0 != fcntl(STDOUT_FILENO, F_SETFL,
|
||||
(state->control.direct_io ? O_DIRECT : 0) | fcntl(STDOUT_FILENO, F_GETFL))) {
|
||||
debug("%s: %s: %s", "(stdout)", "fcntl", strerror(errno));
|
||||
if (0 != fcntl(state->control.output_fd, F_SETFL,
|
||||
(state->control.direct_io ? O_DIRECT : 0) |
|
||||
fcntl(state->control.output_fd, F_GETFL))) {
|
||||
debug("%s: %s: %s",
|
||||
NULL == state->control.output_name ? "(null)" : state->control.output_name,
|
||||
"fcntl", strerror(errno));
|
||||
}
|
||||
}
|
||||
state->control.direct_io_changed = false;
|
||||
@@ -905,10 +1006,10 @@ ssize_t pv_transfer(pvstate_t state, int fd, bool *eof_in, bool *eof_out, off_t
|
||||
*/
|
||||
if (NULL == state->transfer.transfer_buffer) {
|
||||
state->transfer.transfer_buffer =
|
||||
pv__allocate_aligned_buffer(fd, state->control.target_buffer_size + 32);
|
||||
pv__allocate_aligned_buffer(state->control.output_fd, fd, state->control.target_buffer_size + 32);
|
||||
if (NULL == state->transfer.transfer_buffer) {
|
||||
pv_error(state, "%s: %s", _("buffer allocation failed"), strerror(errno));
|
||||
state->status.exit_status |= 64;
|
||||
state->status.exit_status |= PV_ERROREXIT_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
state->transfer.buffer_size = state->control.target_buffer_size;
|
||||
@@ -923,7 +1024,8 @@ ssize_t pv_transfer(pvstate_t state, int fd, bool *eof_in, bool *eof_out, off_t
|
||||
*/
|
||||
if (state->transfer.buffer_size < state->control.target_buffer_size) {
|
||||
char *newptr;
|
||||
newptr = pv__allocate_aligned_buffer(fd, state->control.target_buffer_size + 32);
|
||||
newptr =
|
||||
pv__allocate_aligned_buffer(state->control.output_fd, fd, state->control.target_buffer_size + 32);
|
||||
if (NULL == newptr) {
|
||||
/*
|
||||
* Reset target if realloc failed so we don't keep
|
||||
@@ -983,10 +1085,10 @@ ssize_t pv_transfer(pvstate_t state, int fd, bool *eof_in, bool *eof_out, off_t
|
||||
|
||||
/*
|
||||
* If we don't think we've finished writing and there's anything
|
||||
* we're allowed to write, look for the stdout becoming writable.
|
||||
* we're allowed to write, look for the output becoming writable.
|
||||
*/
|
||||
if ((!(*eof_out)) && (state->transfer.to_write > 0)) {
|
||||
check_write_fd = STDOUT_FILENO;
|
||||
check_write_fd = state->control.output_fd;
|
||||
}
|
||||
|
||||
ready_to_read = false;
|
||||
@@ -1009,7 +1111,7 @@ ssize_t pv_transfer(pvstate_t state, int fd, bool *eof_in, bool *eof_out, off_t
|
||||
/*@+compdef@ */
|
||||
/* splint - see previous pv_current_file_name() calls. */
|
||||
|
||||
state->status.exit_status |= 16;
|
||||
state->status.exit_status |= PV_ERROREXIT_TRANSFER;
|
||||
|
||||
return -1;
|
||||
}
|
||||
@@ -1044,9 +1146,9 @@ ssize_t pv_transfer(pvstate_t state, int fd, bool *eof_in, bool *eof_out, off_t
|
||||
}
|
||||
|
||||
/*
|
||||
* If there is data to write, and stdout is ready to receive it, and
|
||||
* we didn't use splice() this time, write some data. Return early
|
||||
* if there was a transient write error.
|
||||
* If there is data to write, and the output is ready to receive it,
|
||||
* and we didn't use splice() this time, write some data.
|
||||
* Return early if there was a transient write error.
|
||||
*/
|
||||
if (ready_to_write
|
||||
#ifdef HAVE_SPLICE
|
||||
@@ -1080,5 +1182,3 @@ ssize_t pv_transfer(pvstate_t state, int fd, bool *eof_in, bool *eof_out, off_t
|
||||
|
||||
return state->transfer.written;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
||||
+11
-5
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Functions for watching file descriptors in other processes.
|
||||
*
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood
|
||||
* Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2024 Andrew Wood
|
||||
*
|
||||
* License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
|
||||
*/
|
||||
@@ -281,6 +281,13 @@ off_t pv_watchfd_position(pvwatchfd_t info)
|
||||
(void) fclose(fptr);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This debugging line can be quite noisy - turned off for now,
|
||||
* uncomment if needed.
|
||||
*
|
||||
* debug("pid:%d fd:%d position:%lld", (int) (info->watch_pid), info->watch_fd, position);
|
||||
*/
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
@@ -478,6 +485,7 @@ int pv_watchpid_scanfds(pvstate_t state,
|
||||
/*@-mustfreeonly@ *//* splint - this is not a leak, this is a new entry. */
|
||||
info_array[use_idx].state->control.name = NULL;
|
||||
info_array[use_idx].state->control.format_string = NULL;
|
||||
info_array[use_idx].state->control.output_name = NULL;
|
||||
/*@+mustfreeonly@ */
|
||||
info_array[use_idx].state->control.default_format[0] = '\0';
|
||||
use_format_string =
|
||||
@@ -497,8 +505,8 @@ int pv_watchpid_scanfds(pvstate_t state,
|
||||
/*@-mustfreeonly@ *//* splint - this is not a leak, this is a new entry. */
|
||||
info_array[use_idx].state->display.display_buffer = NULL;
|
||||
info_array[use_idx].state->display.display_buffer_size = 0;
|
||||
info_array[use_idx].state->display.history = NULL;
|
||||
info_array[use_idx].state->display.history_len = 0;
|
||||
info_array[use_idx].state->calc.history = NULL;
|
||||
info_array[use_idx].state->calc.history_len = 0;
|
||||
/*@+mustfreeonly@ */
|
||||
pv_state_average_rate_window_set(info_array[use_idx].state, state->control.average_rate_window);
|
||||
|
||||
@@ -644,5 +652,3 @@ void pv_watchpid_setname(pvstate_t state, pvwatchfd_t info)
|
||||
|
||||
debug("%s: %d: [%s]", "set name for fd", info->watch_fd, info->display_name);
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
# 1MiB, described here:
|
||||
# http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=586763
|
||||
|
||||
# Dummy assignments for "shellcheck".
|
||||
testSubject="${testSubject:-false}"; workFile1="${workFile1:-.tmp1}"
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
true "${workFile1:?not set - call this from 'make check'}"
|
||||
|
||||
# Transfer 1500kB of data in a bursty fashion.
|
||||
#
|
||||
@@ -28,5 +28,3 @@ test "${lineLengthCount}" = "1" && exit 0
|
||||
echo "variable line lengths detected"
|
||||
tr '\r' '\n' < "${workFile1}"
|
||||
exit 1
|
||||
|
||||
# EOF
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
# but for rate, not bytes transferred.
|
||||
|
||||
# Dummy assignments for "shellcheck".
|
||||
testSubject="${testSubject:-false}"; workFile1="${workFile1:-.tmp1}"
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
true "${workFile1:?not set - call this from 'make check'}"
|
||||
|
||||
# Transfer 1500kB of data in a bursty fashion.
|
||||
#
|
||||
@@ -29,5 +30,3 @@ test "${lineLengthCount}" = "1" && exit 0
|
||||
echo "variable line lengths detected"
|
||||
tr '\r' '\n' < "${workFile1}"
|
||||
exit 1
|
||||
|
||||
# EOF
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
#
|
||||
# Test that "make install" installs the expected minimum set of files.
|
||||
|
||||
# Dummy assignments for "shellcheck".
|
||||
testSubject="${testSubject:-false}"; workFile1="${workFile1:-.tmp1}"
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
true "${workFile1:?not set - call this from 'make check'}"
|
||||
|
||||
makeDir="${testSubject%/*}"
|
||||
if ! test -d "${makeDir}"; then
|
||||
@@ -39,5 +39,3 @@ fi
|
||||
|
||||
rm -rf "${testInstallDir}"
|
||||
exit "${exitStatus}"
|
||||
|
||||
# EOF
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
# Check that the average transfer rate counter changes, but not more than it
|
||||
# should.
|
||||
|
||||
# Dummy assignments for "shellcheck".
|
||||
testSubject="${testSubject:-false}"; workFile1="${workFile1:-.tmp1}"
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
true "${workFile1:?not set - call this from 'make check'}"
|
||||
|
||||
# Transfer 210 bytes as 100 bytes, a 1 second gap, 110 bytes, and another 1
|
||||
# second gap.
|
||||
@@ -27,5 +27,3 @@ test "${lineCount}" -lt 2 && exit 0
|
||||
echo "average rate varied more than expected"
|
||||
tr '\r' '\n' < "${workFile1}"
|
||||
exit 1
|
||||
|
||||
# EOF
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
#
|
||||
# Check that the byte counter counts in bits when --bits is selected.
|
||||
|
||||
# Dummy assignments for "shellcheck".
|
||||
testSubject="${testSubject:-false}"; workFile1="${workFile1:-.tmp1}"
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
true "${workFile1:?not set - call this from 'make check'}"
|
||||
|
||||
dd if=/dev/zero bs=100 count=1 2>/dev/null \
|
||||
| "${testSubject}" -f -b -8 >/dev/null 2>"${workFile1}"
|
||||
@@ -13,5 +13,3 @@ test "${counterValue}" = "800b" && exit 0
|
||||
|
||||
echo "unexpected bit counter value: ${counterValue}"
|
||||
exit 1
|
||||
|
||||
# EOF
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
#
|
||||
# Check that "--buffer-percent" displays correctly.
|
||||
|
||||
# Dummy assignments for "shellcheck".
|
||||
testSubject="${testSubject:-false}"; workFile1="${workFile1:-.tmp1}"
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
true "${workFile1:?not set - call this from 'make check'}"
|
||||
|
||||
# The output should show 100% and 0% as the buffer initially fills up due to
|
||||
# there being nowhere to write it to, and then empties.
|
||||
@@ -17,5 +17,3 @@ test "${differentLines}" -gt 1 && exit 0
|
||||
echo "expected output changes not seen"
|
||||
tr '\r' '\n' < "${workFile1}" | sed 's/^ *$/d' | sort | uniq
|
||||
exit 1
|
||||
|
||||
# EOF
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
#
|
||||
# Check that the byte counter counts.
|
||||
|
||||
# Dummy assignments for "shellcheck".
|
||||
testSubject="${testSubject:-false}"; workFile1="${workFile1:-.tmp1}"
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
true "${workFile1:?not set - call this from 'make check'}"
|
||||
|
||||
dd if=/dev/zero bs=100 count=1 2>/dev/null \
|
||||
| "${testSubject}" -f -b >/dev/null 2>"${workFile1}"
|
||||
@@ -13,5 +13,3 @@ test "${counterValue}" = "100B" && exit 0
|
||||
|
||||
echo "unexpected byte counter value: ${counterValue}"
|
||||
exit 1
|
||||
|
||||
# EOF
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
#
|
||||
# Check that the estimated time counter counts.
|
||||
|
||||
# Dummy assignments for "shellcheck".
|
||||
testSubject="${testSubject:-false}"; workFile1="${workFile1:-.tmp1}"
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
true "${workFile1:?not set - call this from 'make check'}"
|
||||
|
||||
dd if=/dev/zero bs=100 count=1 2>/dev/null \
|
||||
| "${testSubject}" -f -e -s 100 -i 0.1 -L 25 >/dev/null 2>"${workFile1}"
|
||||
@@ -29,5 +29,3 @@ if ! test "${valueCount}" -lt 12; then
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
# EOF
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
#
|
||||
# Check that the estimated time counter can show the end time of day.
|
||||
|
||||
# Dummy assignments for "shellcheck".
|
||||
testSubject="${testSubject:-false}"; workFile1="${workFile1:-.tmp1}"
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
true "${workFile1:?not set - call this from 'make check'}"
|
||||
|
||||
dd if=/dev/zero bs=100 count=1 2>/dev/null \
|
||||
| "${testSubject}" -f -I -s 100 -i 0.1 -L 25 >/dev/null 2>"${workFile1}"
|
||||
@@ -28,5 +28,3 @@ if ! test "${valueCount}" -lt 8; then
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
# EOF
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
#
|
||||
# Check that "--last-written" works.
|
||||
|
||||
# Dummy assignments for "shellcheck".
|
||||
testSubject="${testSubject:-false}"; workFile1="${workFile1:-.tmp1}"
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
true "${workFile1:?not set - call this from 'make check'}"
|
||||
|
||||
# Slowly write a sequence of numbers (rate-limited by another `pv' instance)
|
||||
# and watch the "--last-written" output of a second `pv' instance to make
|
||||
@@ -30,5 +30,3 @@ if ! test "${lastLine}" = "${expectedLastLine}"; then
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
# EOF
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
#
|
||||
# Check that numeric output outputs some percentages.
|
||||
|
||||
# Dummy assignments for "shellcheck".
|
||||
testSubject="${testSubject:-false}"; workFile1="${workFile1:-.tmp1}"
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
true "${workFile1:?not set - call this from 'make check'}"
|
||||
|
||||
# Process 100 bytes at 100 bytes per second, updating every 0.1 seconds for
|
||||
# around 10 output lines.
|
||||
@@ -31,5 +31,3 @@ if ! test "${finalLine}" = "100"; then
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
# EOF
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
# Check that numeric output gives a byte count instead of a percentage when
|
||||
# used with -b.
|
||||
|
||||
# Dummy assignments for "shellcheck".
|
||||
testSubject="${testSubject:-false}"; workFile1="${workFile1:-.tmp1}"
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
true "${workFile1:?not set - call this from 'make check'}"
|
||||
|
||||
# Process 500 bytes at 500 bytes per second, updating every 0.1 seconds for
|
||||
# around 10 output lines.
|
||||
@@ -30,5 +30,3 @@ if ! test "${finalLine}" = "500"; then
|
||||
echo "final byte count was not 500 (${finalLine})"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# EOF
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
# Check that numeric output shows line counts instead of percentages, when
|
||||
# used in line mode together with bytes mode.
|
||||
|
||||
# Dummy assignments for "shellcheck".
|
||||
testSubject="${testSubject:-false}"; workFile1="${workFile1:-.tmp1}"; workFile2="${workFile2:-.tmp2}"
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
true "${workFile1:?not set - call this from 'make check'}"
|
||||
true "${workFile2:?not set - call this from 'make check'}"
|
||||
|
||||
# Pass through 100 lines.
|
||||
#
|
||||
@@ -33,5 +34,3 @@ if ! test "${finalStdoutLine}" = "100"; then
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
# EOF
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
#
|
||||
# Check that numeric output gives a timer when used with -t.
|
||||
|
||||
# Dummy assignments for "shellcheck".
|
||||
testSubject="${testSubject:-false}"; workFile1="${workFile1:-.tmp1}"
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
true "${workFile1:?not set - call this from 'make check'}"
|
||||
|
||||
# Process 100 bytes at 100 bytes per second, updating every 0.1 seconds for
|
||||
# around 10 output lines.
|
||||
@@ -15,20 +15,20 @@ lineCount=$(wc -l < "${workFile1}" | tr -dc '0-9')
|
||||
timesCount=$(tr ',' '.' < "${workFile1}" | awk '{print int(10*$1)}' | sort -n | uniq | wc -l | tr -dc '0-9')
|
||||
finalPercentage=$(sed -n '$p' < "${workFile1}" | awk '{print $2}')
|
||||
|
||||
# The number of output lines should be >8 and <13, and the number of
|
||||
# different elapsed times should be at least 7. The last percentage should
|
||||
# The number of output lines should be >7 and <13, and the number of
|
||||
# different elapsed times should be at least 6. The last percentage should
|
||||
# be 100.
|
||||
#
|
||||
if ! test "${lineCount}" -gt 8; then
|
||||
echo "fewer than 9 output lines (${lineCount})"
|
||||
if ! test "${lineCount}" -gt 7; then
|
||||
echo "fewer than 8 output lines (${lineCount})"
|
||||
exit 1
|
||||
fi
|
||||
if ! test "${lineCount}" -lt 13; then
|
||||
echo "more than 12 output lines (${lineCount})"
|
||||
exit 1
|
||||
fi
|
||||
if ! test "${timesCount}" -gt 7; then
|
||||
echo "fewer than 8 different elapsed times (${timesCount})"
|
||||
if ! test "${timesCount}" -gt 5; then
|
||||
echo "fewer than 6 different elapsed times (${timesCount})"
|
||||
exit 1
|
||||
fi
|
||||
if ! test "${finalPercentage}" = "100"; then
|
||||
@@ -37,5 +37,3 @@ if ! test "${finalPercentage}" = "100"; then
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
# EOF
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
#
|
||||
# Check that the progress bar moves when data is coming in.
|
||||
|
||||
# Dummy assignments for "shellcheck".
|
||||
testSubject="${testSubject:-false}"; workFile1="${workFile1:-.tmp1}"
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
true "${workFile1:?not set - call this from 'make check'}"
|
||||
|
||||
dd if=/dev/zero bs=100 count=1 2>/dev/null \
|
||||
| "${testSubject}" -f -p -i 0.1 -L 500 >/dev/null 2>"${workFile1}"
|
||||
@@ -18,5 +18,3 @@ if ! test "${lineCount}" -gt 2; then
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
# EOF
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
#
|
||||
# Check that the progress bar increases in size when data is coming in.
|
||||
|
||||
# Dummy assignments for "shellcheck".
|
||||
testSubject="${testSubject:-false}"; workFile1="${workFile1:-.tmp1}"
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
true "${workFile1:?not set - call this from 'make check'}"
|
||||
|
||||
dd if=/dev/zero bs=100 count=1 2>/dev/null \
|
||||
| "${testSubject}" -f -p -i 0.1 -L 50 -s 100 >/dev/null 2>"${workFile1}"
|
||||
@@ -28,5 +28,3 @@ if ! test "${differentBarLengthsCount}" -gt 5; then
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
# EOF
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
#
|
||||
# Check that the -q option shuts everything up.
|
||||
|
||||
# Dummy assignments for "shellcheck".
|
||||
testSubject="${testSubject:-false}"; workFile1="${workFile1:-.tmp1}"
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
true "${workFile1:?not set - call this from 'make check'}"
|
||||
|
||||
dd if=/dev/zero bs=1000 count=5 2>/dev/null \
|
||||
| "${testSubject}" -f -q -i 0.1 -L 5000 >/dev/null 2>"${workFile1}"
|
||||
@@ -15,5 +15,3 @@ if test -s "${workFile1}"; then
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
# EOF
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
#
|
||||
# Check that the transfer rate counter changes.
|
||||
|
||||
# Dummy assignments for "shellcheck".
|
||||
testSubject="${testSubject:-false}"; workFile1="${workFile1:-.tmp1}"
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
true "${workFile1:?not set - call this from 'make check'}"
|
||||
|
||||
# Transfer 200 bytes as two 100-byte blocks with a 2-second gap between.
|
||||
#
|
||||
@@ -27,5 +27,3 @@ if ! test "${rateCount}" -gt 2; then
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
# EOF
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
#
|
||||
# Check that the elapsed time counter does count up.
|
||||
|
||||
# Dummy assignments for "shellcheck".
|
||||
testSubject="${testSubject:-false}"; workFile1="${workFile1:-.tmp1}"
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
true "${workFile1:?not set - call this from 'make check'}"
|
||||
|
||||
# Transfer a zero amount of data, but take 3 seconds to do it.
|
||||
#
|
||||
@@ -18,5 +18,3 @@ if ! test "${valueCount}" -gt 1; then
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
# EOF
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
# Check that the process ID can be written to a file as described in the
|
||||
# manual.
|
||||
|
||||
# Dummy assignments for "shellcheck".
|
||||
testSubject="${testSubject:-false}"; workFile1="${workFile1:-.tmp1}"
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
true "${workFile1:?not set - call this from 'make check'}"
|
||||
|
||||
# Check we can run "kill -s 0".
|
||||
if ! kill -s 0 $$ >/dev/null 2>&1; then
|
||||
@@ -46,5 +46,3 @@ if ! test "${pidValid}" = "1"; then
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
# EOF
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
#
|
||||
# Check that size arguments are processed correctly.
|
||||
|
||||
# Dummy assignments for "shellcheck".
|
||||
testSubject="${testSubject:-false}"
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
|
||||
# Pass size argument $1 and check that the last reported number is $2.
|
||||
checkSizeArgument () {
|
||||
@@ -20,5 +19,3 @@ checkSizeArgument 1M 1048576
|
||||
checkSizeArgument 8G 8589934592
|
||||
|
||||
exit 0
|
||||
|
||||
# EOF
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
#
|
||||
# Check that data can be just passed straight through.
|
||||
|
||||
# Dummy assignment for "shellcheck".
|
||||
testSubject="${testSubject:-false}"
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
|
||||
inputString="TESTING"
|
||||
outputString=$(printf "%s" "${inputString}" | "${testSubject}" 2>/dev/null) || { echo "unexpected failure code"; exit 1; }
|
||||
@@ -23,5 +22,3 @@ if ! test "${inputString}" = "${outputString}"; then
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
# EOF
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
# Transfer a large chunk of data through pv and check data correctness
|
||||
# afterwards.
|
||||
|
||||
# Dummy assignments for "shellcheck".
|
||||
testSubject="${testSubject:-false}"; workFile1="${workFile1:-.tmp1}"; workFile2="${workFile2:-.tmp2}"
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
true "${workFile1:?not set - call this from 'make check'}"
|
||||
true "${workFile2:?not set - call this from 'make check'}"
|
||||
|
||||
# generate some data
|
||||
dd if=/dev/urandom of="${workFile1}" bs=1024 count=10240 2>/dev/null
|
||||
@@ -19,5 +20,3 @@ outputChecksum=$(cksum "${workFile2}" | awk '{print $1}')
|
||||
test "${inputChecksum}" = "${outputChecksum}" || exit 1
|
||||
|
||||
exit 0
|
||||
|
||||
# EOF
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
# Transfer a large chunk of data through pv using pipes, sending it in a
|
||||
# bursty fashion, and check data correctness afterwards.
|
||||
|
||||
# Dummy assignments for "shellcheck".
|
||||
testSubject="${testSubject:-false}"; workFile1="${workFile1:-.tmp1}"; workFile2="${workFile2:-.tmp2}"
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
true "${workFile1:?not set - call this from 'make check'}"
|
||||
true "${workFile2:?not set - call this from 'make check'}"
|
||||
|
||||
# generate some data
|
||||
dd if=/dev/urandom of="${workFile1}" bs=1024 count=10240 2>/dev/null
|
||||
@@ -52,5 +53,3 @@ if ! test "${inputChecksum}" = "${outputChecksum}"; then
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
# EOF
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
#
|
||||
# Make sure that files larger than 2GB are supported.
|
||||
|
||||
# Dummy assignments for "shellcheck".
|
||||
testSubject="${testSubject:-false}"; workFile1="${workFile1:-.tmp1}"; workFile2="${workFile2:-.tmp2}"
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
true "${workFile1:?not set - call this from 'make check'}"
|
||||
true "${workFile2:?not set - call this from 'make check'}"
|
||||
|
||||
# Check there is enough free space for this test.
|
||||
workFile1Dir="${workFile1%/*}"
|
||||
@@ -76,5 +77,3 @@ if ! test "${bytesReported}" -eq "${fileSize}"; then
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
# EOF
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
#
|
||||
# Check that there is no SIGPIPE or dropped data on bigger data transfers.
|
||||
|
||||
# Dummy assignments for "shellcheck".
|
||||
testSubject="${testSubject:-false}"
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
|
||||
# We nead GNU head. On some platforms it is named ghead instead of head.
|
||||
HEAD="head"
|
||||
@@ -36,5 +35,3 @@ if ! test "${stopAtByteCount}" = "${bytesTransferred}"; then
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
# EOF
|
||||
|
||||
@@ -3,8 +3,11 @@
|
||||
# Try repeatedly messaging a transfer process, and make sure the data stays
|
||||
# intact.
|
||||
|
||||
# Dummy assignments for "shellcheck".
|
||||
testSubject="${testSubject:-false}"; workFile1="${workFile1:-.tmp1}"; workFile2="${workFile2:-.tmp2}"; workFile3="${workFile3:-.tmp3}"; workFile4="${workFile4:-.tmp4}"
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
true "${workFile1:?not set - call this from 'make check'}"
|
||||
true "${workFile2:?not set - call this from 'make check'}"
|
||||
true "${workFile3:?not set - call this from 'make check'}"
|
||||
true "${workFile4:?not set - call this from 'make check'}"
|
||||
|
||||
# Do nothing if it is not supported.
|
||||
if ! "${testSubject}" -h 2>/dev/null | grep -Eq "^ -R,"; then
|
||||
@@ -57,5 +60,3 @@ if ! test "${inputChecksum}" = "${outputChecksum}"; then
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
# EOF
|
||||
|
||||
@@ -3,8 +3,12 @@
|
||||
# Run valgrind's memory checker against a process using various different
|
||||
# transfer options.
|
||||
|
||||
# Dummy assignments for "shellcheck".
|
||||
sourcePath="${sourcePath:-.}"; testSubject="${testSubject:-false}"; workFile1="${workFile1:-.tmp1}"; workFile2="${workFile2:-.tmp2}"; workFile3="${workFile3:-.tmp3}"; workFile4="${workFile4:-.tmp4}"
|
||||
true "${sourcePath:?not set - call this from 'make check'}"
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
true "${workFile1:?not set - call this from 'make check'}"
|
||||
true "${workFile2:?not set - call this from 'make check'}"
|
||||
true "${workFile3:?not set - call this from 'make check'}"
|
||||
true "${workFile4:?not set - call this from 'make check'}"
|
||||
|
||||
# Load the valgrind function.
|
||||
. "${sourcePath}/tests/run-valgrind.sh"
|
||||
@@ -34,5 +38,3 @@ seq -w 3 1 100 \
|
||||
| { runWithValgrind -bnl -i 0.2 -f -L 100 2>"${workFile1}" > "${workFile2}"; } 4>&1 || exit 1
|
||||
|
||||
exit 0
|
||||
|
||||
# EOF
|
||||
|
||||
Executable
+30
@@ -0,0 +1,30 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Run valgrind's memory checker against a process that sets is process
|
||||
# title.
|
||||
|
||||
true "${sourcePath:?not set - call this from 'make check'}"
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
true "${workFile1:?not set - call this from 'make check'}"
|
||||
true "${workFile2:?not set - call this from 'make check'}"
|
||||
true "${workFile3:?not set - call this from 'make check'}"
|
||||
true "${workFile4:?not set - call this from 'make check'}"
|
||||
|
||||
# Load the valgrind function.
|
||||
. "${sourcePath}/tests/run-valgrind.sh"
|
||||
|
||||
# Without an extra format string.
|
||||
(dd if=/dev/zero bs=100 count=1 2>/dev/null;
|
||||
sleep 1;
|
||||
dd if=/dev/zero bs=110 count=1 2>/dev/null;
|
||||
sleep 1;
|
||||
) | { runWithValgrind -f -i 0.5 -a -x processtitle >/dev/null 2>"${workFile1}"; } 4>&1 || exit 1
|
||||
|
||||
# With an extra format string.
|
||||
(dd if=/dev/zero bs=100 count=1 2>/dev/null;
|
||||
sleep 1;
|
||||
dd if=/dev/zero bs=110 count=1 2>/dev/null;
|
||||
sleep 1;
|
||||
) | { runWithValgrind -f -i 0.5 -a -x 'processtitle:%t %b' >/dev/null 2>"${workFile1}"; } 4>&1 || exit 1
|
||||
|
||||
exit 0
|
||||
@@ -2,8 +2,12 @@
|
||||
#
|
||||
# Run valgrind's memory checker while receiving remote control commands.
|
||||
|
||||
# Dummy assignments for "shellcheck".
|
||||
sourcePath="${sourcePath:-.}"; testSubject="${testSubject:-false}"; workFile1="${workFile1:-.tmp1}"; workFile2="${workFile2:-.tmp2}"; workFile3="${workFile3:-.tmp3}"; workFile4="${workFile4:-.tmp4}"
|
||||
true "${sourcePath:?not set - call this from 'make check'}"
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
true "${workFile1:?not set - call this from 'make check'}"
|
||||
true "${workFile2:?not set - call this from 'make check'}"
|
||||
true "${workFile3:?not set - call this from 'make check'}"
|
||||
true "${workFile4:?not set - call this from 'make check'}"
|
||||
|
||||
# Do nothing if it is not supported.
|
||||
if ! "${testSubject}" -h 2>/dev/null | grep -Eq "^ -R,"; then
|
||||
@@ -39,5 +43,3 @@ done
|
||||
{ runWithValgrind -L 100k -i 0.1 -f -P "${workFile3}" "${workFile1}" > "${workFile2}" 2>/dev/null; } 4>&1 || exit 1
|
||||
|
||||
exit 0
|
||||
|
||||
# EOF
|
||||
|
||||
@@ -3,8 +3,12 @@
|
||||
# Run valgrind's memory checker while using remote control to control
|
||||
# another process.
|
||||
|
||||
# Dummy assignments for "shellcheck".
|
||||
sourcePath="${sourcePath:-.}"; testSubject="${testSubject:-false}"; workFile1="${workFile1:-.tmp1}"; workFile2="${workFile2:-.tmp2}"; workFile3="${workFile3:-.tmp3}"; workFile4="${workFile4:-.tmp4}"
|
||||
true "${sourcePath:?not set - call this from 'make check'}"
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
true "${workFile1:?not set - call this from 'make check'}"
|
||||
true "${workFile2:?not set - call this from 'make check'}"
|
||||
true "${workFile3:?not set - call this from 'make check'}"
|
||||
true "${workFile4:?not set - call this from 'make check'}"
|
||||
|
||||
# Do nothing if it is not supported.
|
||||
if ! "${testSubject}" -h 2>/dev/null | grep -Eq "^ -R,"; then
|
||||
@@ -35,5 +39,3 @@ runWithValgrind -R "$(cat "${workFile3}")" -L 10M 4>&1 || exit 1
|
||||
wait
|
||||
|
||||
exit 0
|
||||
|
||||
# EOF
|
||||
|
||||
Executable
+61
@@ -0,0 +1,61 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Run valgrind's memory checker against a process using the --watchfd
|
||||
# option.
|
||||
|
||||
true "${sourcePath:?not set - call this from 'make check'}"
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
true "${workFile1:?not set - call this from 'make check'}"
|
||||
true "${workFile2:?not set - call this from 'make check'}"
|
||||
true "${workFile3:?not set - call this from 'make check'}"
|
||||
true "${workFile4:?not set - call this from 'make check'}"
|
||||
|
||||
# Load the valgrind function.
|
||||
. "${sourcePath}/tests/run-valgrind.sh"
|
||||
|
||||
# Skip the test if "-d" is not available.
|
||||
if ! "${testSubject}" -h | grep -Fq ' -d'; then
|
||||
echo "no \`--watchfd' / \`-d' option on this platform"
|
||||
exit 77
|
||||
fi
|
||||
|
||||
# Skip the test if "-d" does not work.
|
||||
sleep 2 &
|
||||
sleep 0.1
|
||||
"${testSubject}" -d "${pid}" -f -i 0.5 >/dev/null 2>"${workFile1}"
|
||||
if grep -Fq ' -d: not available' "${workFile1}"; then
|
||||
echo "no \`--watchfd' / \`-d' option on this platform"
|
||||
exit 77
|
||||
fi
|
||||
|
||||
# Check "--watchfd PID:FD".
|
||||
# See the "Watchfd" tests for more detail.
|
||||
seq 1 100 > "${workFile1}"
|
||||
# shellcheck disable=SC2030
|
||||
(sleep 1; read -r line; sleep 1; read -r line; sleep 1) <"${workFile1}" &
|
||||
pid=$!
|
||||
sleep 0.1
|
||||
{ runWithValgrind -d "${pid}:0" -f -i 0.5 >/dev/null 2>&1; } 4>&1 || exit 1
|
||||
|
||||
# Check "--watchfd PID".
|
||||
seq 1 100 > "${workFile1}"
|
||||
seq 1 300 > "${workFile2}"
|
||||
# shellcheck disable=SC2030
|
||||
(
|
||||
sleep 1
|
||||
read -r line
|
||||
exec 9<"${workFile2}"
|
||||
sleep 1
|
||||
exec 8<"${workFile1}"
|
||||
exec 7</dev/null
|
||||
sleep 1
|
||||
exec 9<&-
|
||||
# shellcheck disable=SC2034
|
||||
read -r line
|
||||
sleep 1
|
||||
) <"${workFile1}" &
|
||||
pid=$!
|
||||
sleep 0.1
|
||||
{ runWithValgrind -d "${pid}" -f -i 0.5 >/dev/null 2>&1; } 4>&1 || exit 1
|
||||
|
||||
exit 0
|
||||
@@ -5,8 +5,9 @@
|
||||
# doesn't check that O_DIRECT is actually being used, it just checks that
|
||||
# data is not being corrupted.
|
||||
|
||||
# Dummy assignments for "shellcheck".
|
||||
testSubject="${testSubject:-false}"; workFile1="${workFile1:-.tmp1}"; workFile2="${workFile2:-.tmp2}"
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
true "${workFile1:?not set - call this from 'make check'}"
|
||||
true "${workFile2:?not set - call this from 'make check'}"
|
||||
|
||||
# generate some data
|
||||
dd if=/dev/urandom of="${workFile1}" bs=1024 count=2560 2>/dev/null
|
||||
@@ -51,5 +52,3 @@ if ! test "${doubleInputChecksum}" = "${outputChecksum}"; then
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
# EOF
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
# Check that the progress bar is produced when "--force" is used, and is not
|
||||
# when it is not, providing stderr is a file.
|
||||
|
||||
# Dummy assignments for "shellcheck".
|
||||
testSubject="${testSubject:-false}"; workFile1="${workFile1:-.tmp1}";
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
true "${workFile1:?not set - call this from 'make check'}"
|
||||
|
||||
dd if=/dev/zero bs=100 count=1 2>/dev/null \
|
||||
| "${testSubject}" -f -p -i 0.1 -L 100 >/dev/null 2>"${workFile1}"
|
||||
@@ -32,5 +32,3 @@ if test -s "${workFile1}"; then
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
# EOF
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
#
|
||||
# Check that the update interval can be set.
|
||||
|
||||
# Dummy assignments for "shellcheck".
|
||||
testSubject="${testSubject:-false}"; workFile1="${workFile1:-.tmp1}"
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
true "${workFile1:?not set - call this from 'make check'}"
|
||||
|
||||
sleep 1 | "${testSubject}" -f -i 0.1 >/dev/null 2>"${workFile1}"
|
||||
|
||||
@@ -17,5 +17,3 @@ if ! test "${lineCount}" -gt 6; then
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
# EOF
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
#
|
||||
# Check that line mode counts lines instead of bytes.
|
||||
|
||||
# Dummy assignments for "shellcheck".
|
||||
testSubject="${testSubject:-false}"; workFile1="${workFile1:-.tmp1}"
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
true "${workFile1:?not set - call this from 'make check'}"
|
||||
|
||||
# Pass through 100 lines.
|
||||
#
|
||||
@@ -28,5 +28,3 @@ if ! test "${lineCount}" -gt 3; then
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
# EOF
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
#
|
||||
# Check that "--size" affects the percentage shown.
|
||||
|
||||
# Dummy assignments for "shellcheck".
|
||||
testSubject="${testSubject:-false}"; workFile1="${workFile1:-.tmp1}"
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
true "${workFile1:?not set - call this from 'make check'}"
|
||||
|
||||
# Process 100 bytes at 100 bytes per second, updating every 0.1 seconds for
|
||||
# around 10 output lines, but set the size to 200.
|
||||
@@ -52,5 +52,3 @@ if ! test "${finalLine}" = "200"; then
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
# EOF
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
# Similar to the "--size" check but, instead, using another file's size with
|
||||
# "--size @".
|
||||
|
||||
# Dummy assignments for "shellcheck".
|
||||
testSubject="${testSubject:-false}"; workFile1="${workFile1:-.tmp1}"; workFile2="${workFile2:-.tmp2}"
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
true "${workFile1:?not set - call this from 'make check'}"
|
||||
true "${workFile2:?not set - call this from 'make check'}"
|
||||
|
||||
# Process 100 bytes at 100 bytes per second, interval 0.1 seconds, with the
|
||||
# size set from a file of $1 bytes and expecting a percentage of $2 at the
|
||||
@@ -45,5 +46,3 @@ sizeCheck 200 50
|
||||
sizeCheck 50 200
|
||||
|
||||
exit 0
|
||||
|
||||
# EOF
|
||||
|
||||
@@ -5,8 +5,9 @@
|
||||
# check that fdatasync() is actually being called, it just checks that data
|
||||
# is not being corrupted.
|
||||
|
||||
# Dummy assignments for "shellcheck".
|
||||
testSubject="${testSubject:-false}"; workFile1="${workFile1:-.tmp1}"; workFile2="${workFile2:-.tmp2}"
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
true "${workFile1:?not set - call this from 'make check'}"
|
||||
true "${workFile2:?not set - call this from 'make check'}"
|
||||
|
||||
# generate some data
|
||||
dd if=/dev/urandom of="${workFile1}" bs=1024 count=2560 2>/dev/null
|
||||
@@ -41,5 +42,3 @@ if ! test "${inputChecksum}" = "${outputChecksum}"; then
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
# EOF
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
#
|
||||
# Check that the terminal width is detected on startup.
|
||||
|
||||
# Dummy assignments for "shellcheck".
|
||||
testSubject="${testSubject:-false}"; workFile1="${workFile1:-.tmp1}"; workFile2="${workFile2:-.tmp2}"
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
true "${workFile1:?not set - call this from 'make check'}"
|
||||
true "${workFile2:?not set - call this from 'make check'}"
|
||||
|
||||
# Skip the test if `tmux' is not available.
|
||||
if ! command -v tmux >/dev/null 2>&1; then
|
||||
@@ -86,5 +87,3 @@ widthTest 400
|
||||
widthTest 20
|
||||
|
||||
exit 0
|
||||
|
||||
# EOF
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
#
|
||||
# A simple test of rate limiting.
|
||||
|
||||
# Dummy assignments for "shellcheck".
|
||||
testSubject="${testSubject:-false}"
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
|
||||
# Transfer 102 bytes at 100 bytes/sec. It should take at least 1 second.
|
||||
#
|
||||
@@ -17,5 +16,3 @@ if test "${startTime}" = "${endTime}"; then
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
# EOF
|
||||
|
||||
@@ -2,8 +2,11 @@
|
||||
#
|
||||
# Try changing the format of a transfer remotely.
|
||||
|
||||
# Dummy assignments for "shellcheck".
|
||||
testSubject="${testSubject:-false}"; workFile1="${workFile1:-.tmp1}"; workFile2="${workFile2:-.tmp2}"; workFile3="${workFile3:-.tmp3}"; workFile4="${workFile4:-.tmp4}"
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
true "${workFile1:?not set - call this from 'make check'}"
|
||||
true "${workFile2:?not set - call this from 'make check'}"
|
||||
true "${workFile3:?not set - call this from 'make check'}"
|
||||
true "${workFile4:?not set - call this from 'make check'}"
|
||||
|
||||
# Do nothing if it is not supported.
|
||||
if ! "${testSubject}" -h 2>/dev/null | grep -Eq "^ -R,"; then
|
||||
@@ -32,5 +35,3 @@ if ! test "${line_lengths}" -gt 1; then
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
# EOF
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
#
|
||||
# Make sure -S stops at the given size.
|
||||
|
||||
# Dummy assignments for "shellcheck".
|
||||
testSubject="${testSubject:-false}"; workFile1="${workFile1:-.tmp1}"; workFile2="${workFile2:-.tmp2}"
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
true "${workFile1:?not set - call this from 'make check'}"
|
||||
true "${workFile2:?not set - call this from 'make check'}"
|
||||
|
||||
# generate some data
|
||||
dd if=/dev/urandom of="${workFile1}" bs=1024 count=10 2>/dev/null
|
||||
@@ -23,5 +24,3 @@ if ! test "${inputChecksum}" = "${outputChecksum}"; then
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
# EOF
|
||||
|
||||
Executable
+75
@@ -0,0 +1,75 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Check that watching a process's file descriptors works as expected.
|
||||
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
true "${workFile1:?not set - call this from 'make check'}"
|
||||
true "${workFile2:?not set - call this from 'make check'}"
|
||||
true "${workFile3:?not set - call this from 'make check'}"
|
||||
|
||||
# Skip the test if "-d" is not available.
|
||||
if ! "${testSubject}" -h | grep -Fq ' -d'; then
|
||||
echo "no \`--watchfd' / \`-d' option on this platform"
|
||||
exit 77
|
||||
fi
|
||||
|
||||
seq 1 100 > "${workFile1}"
|
||||
seq 1 300 > "${workFile2}"
|
||||
|
||||
# Run a background process to perform a few reads from a file, opening a
|
||||
# second file after a moment.
|
||||
# NB we just export line to make shellcheck think it's used.
|
||||
(
|
||||
export line
|
||||
sleep 1
|
||||
read -r line
|
||||
exec 9<"${workFile2}"
|
||||
sleep 1
|
||||
read -r line
|
||||
sleep 1
|
||||
) <"${workFile1}" &
|
||||
pid=$!
|
||||
|
||||
sleep 0.1
|
||||
"${testSubject}" -d "${pid}" -f -i 0.5 >/dev/null 2>"${workFile3}"
|
||||
|
||||
# Skip the test if "-d" does not work.
|
||||
if grep -Fq ' -d: not available' "${workFile3}"; then
|
||||
echo "no \`--watchfd' / \`-d' option on this platform"
|
||||
exit 77
|
||||
fi
|
||||
|
||||
# Process the output to make it easier to handle.
|
||||
# NB "ESC [ A" is "cursor up", we turn that into "-" and a newline.
|
||||
tr '\r' '\n' < "${workFile3}" | sed 's/.\[A/-!/g' | tr '!' '\n' > "${workFile1}"
|
||||
|
||||
# We should see at least 2 file positions for fd 0.
|
||||
positionsReported="$(awk '/^ *0:/ {print $2}' < "${workFile1}" | sort -n | uniq)"
|
||||
differentNumbers="$(printf "%s\n" "${positionsReported}" | grep -Ec .)"
|
||||
if ! test "${differentNumbers}" -gt 1; then
|
||||
printf "%s\n" "Expected at least 2 different numbers to be output for fd 0"
|
||||
printf "%s:\n%s\n" "Positions reported" "${positionsReported}"
|
||||
printf "%s: %s\n" "Number of different values seen" "${differentNumbers}"
|
||||
printf "%s\n" "Raw output:"
|
||||
cat "${workFile1}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# We should see file descriptor 9 appear.
|
||||
if ! grep -Eq '^ *9:' < "${workFile1}"; then
|
||||
printf "%s\n" "Expected to see information for fd 9"
|
||||
printf "%s\n" "Raw output:"
|
||||
cat "${workFile1}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# We should see the last 6 characters of fd 9's filename appear.
|
||||
lastChars="$(printf "%s\n" "${workFile2}" | rev | cut -b1-6 | rev)"
|
||||
if ! grep -Fq "${lastChars}:" < "${workFile1}"; then
|
||||
printf "%s\n" "Expected to see a filename for fd 9"
|
||||
printf "%s\n" "Raw output:"
|
||||
cat "${workFile1}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
Executable
+43
@@ -0,0 +1,43 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Check that watching a single file descriptor works as expected.
|
||||
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
true "${workFile1:?not set - call this from 'make check'}"
|
||||
true "${workFile2:?not set - call this from 'make check'}"
|
||||
|
||||
# Skip the test if "-d" is not available.
|
||||
if ! "${testSubject}" -h | grep -Fq ' -d'; then
|
||||
echo "no \`--watchfd' / \`-d' option on this platform"
|
||||
exit 77
|
||||
fi
|
||||
|
||||
seq 1 100 > "${workFile1}"
|
||||
|
||||
# Run a background process to perform a few reads from a file.
|
||||
# NB we just export line to make shellcheck think it's used.
|
||||
(export line; sleep 1; read -r line; sleep 1; read -r line; sleep 1) <"${workFile1}" &
|
||||
pid=$!
|
||||
|
||||
sleep 0.1
|
||||
"${testSubject}" -d "${pid}:0" -f -i 0.5 >/dev/null 2>"${workFile2}"
|
||||
|
||||
# Skip the test if "-d" does not work.
|
||||
if grep -Fq ' -d: not available' "${workFile2}"; then
|
||||
echo "no \`--watchfd' / \`-d' option on this platform"
|
||||
exit 77
|
||||
fi
|
||||
|
||||
# There should be at least 2 different numbers starting the output lines.
|
||||
positionsReported="$(tr '\r' '\n' < "${workFile2}" | awk '{print $1}' | sort -n | uniq)"
|
||||
differentNumbers="$(printf "%s\n" "${positionsReported}" | grep -Ec .)"
|
||||
if ! test "${differentNumbers}" -gt 1; then
|
||||
printf "%s\n" "Expected at least 2 different numbers to be output"
|
||||
printf "%s:\n%s\n" "Positions reported" "${positionsReported}"
|
||||
printf "%s: %s\n" "Number of different values seen" "${differentNumbers}"
|
||||
printf "%s\n" "Raw output:"
|
||||
tr '\r' '\n' < "${workFile2}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
+19
-6
@@ -21,8 +21,9 @@
|
||||
# Output file for failures.
|
||||
valgrindOutputFile="valgrind.out"
|
||||
|
||||
# Dummy assignments for "shellcheck".
|
||||
testSubject="${testSubject:-false}"; workFile4="${workFile4:-.tmp4}"
|
||||
true "${testSubject:?not set - call this from 'make check'}"
|
||||
true "${workFile4:?not set - call this from 'make check'}"
|
||||
true "${workFile5:?not set - call this from 'make check'}"
|
||||
|
||||
if ! command -v valgrind >/dev/null 2>&1; then
|
||||
echo "test requires \`valgrind'"
|
||||
@@ -36,13 +37,27 @@ done
|
||||
|
||||
runWithValgrind () {
|
||||
|
||||
cat > "${workFile5}" <<EOF
|
||||
{
|
||||
ignore-initproctitle-leak
|
||||
Memcheck:Leak
|
||||
fun:malloc
|
||||
fun:initproctitle
|
||||
fun:main
|
||||
}
|
||||
EOF
|
||||
|
||||
true > "${workFile4}"
|
||||
valgrind --tool=memcheck \
|
||||
--verbose --show-error-list=yes --log-fd=3 \
|
||||
--verbose \
|
||||
--show-error-list=yes \
|
||||
--suppressions="${workFile5}" \
|
||||
--log-file="${workFile4}" \
|
||||
--error-exitcode=125 \
|
||||
--track-fds=yes \
|
||||
--leak-check=full \
|
||||
"${testSubject}" "$@" \
|
||||
3>"${workFile4}" 4<&-
|
||||
4<&- 9<&-
|
||||
|
||||
returnValue=$?
|
||||
|
||||
@@ -62,5 +77,3 @@ runWithValgrind () {
|
||||
|
||||
return "${returnValue}"
|
||||
}
|
||||
|
||||
# EOF
|
||||
|
||||
+5
-2
@@ -6,6 +6,8 @@
|
||||
# Tests must exit with 0 for success, 1 for failure, 77 to skip the test, or
|
||||
# 99 for a fatal error with the test framework.
|
||||
|
||||
true "${srcdir:?not set - call this from 'make check'}"
|
||||
|
||||
# Parameters.
|
||||
testSubject="./pv"
|
||||
sourcePath="${srcdir}"
|
||||
@@ -20,9 +22,10 @@ workFile1=$(mktemp 2>/dev/null) || workFile1="./.tmp1"
|
||||
workFile2=$(mktemp 2>/dev/null) || workFile2="./.tmp2"
|
||||
workFile3=$(mktemp 2>/dev/null) || workFile3="./.tmp3"
|
||||
workFile4=$(mktemp 2>/dev/null) || workFile4="./.tmp4"
|
||||
workFile5=$(mktemp 2>/dev/null) || workFile4="./.tmp5"
|
||||
|
||||
# Clean up the temporary files on exit, in case we are interrupted.
|
||||
trap 'rm -f "${workFile1}" "${workFile2}" "${workFile3}" "${workFile4}"' EXIT
|
||||
trap 'rm -f "${workFile1}" "${workFile2}" "${workFile3}" "${workFile4}" "${workFile5}"' EXIT
|
||||
|
||||
# Variables used by the test scripts.
|
||||
export testSubject sourcePath workFile1 workFile2 workFile3 workFile4
|
||||
export testSubject sourcePath workFile1 workFile2 workFile3 workFile4 workFile5
|
||||
|
||||
Reference in New Issue
Block a user