58 Commits
Author SHA1 Message Date
Andrew Wood b42399e9a9 Timestamp update. 2024-07-18 22:23:48 +01:00
Andrew Wood ba72056bf2 Version bump. 2024-07-18 22:10:57 +01:00
Andrew Wood b8e4a51228 Update line numbers. 2024-07-18 22:08:34 +01:00
Andrew Wood 0b12f7db42 Update TODO to reflect issue tracker. 2024-07-18 22:01:36 +01:00
Andrew Wood 5053cffdad Further clarification of #92, #93. 2024-07-17 07:45:13 +01:00
Andrew Wood 02f852604f Add #93. 2024-07-17 07:42:18 +01:00
Andrew Wood e4ab8c56a0 Minor adjustment to comments. 2024-07-17 07:41:48 +01:00
Andrew Wood 86016d41d7 Merge pull request 'Improve description and comments for blocking-write() after select()' (#93) from eborisch/pv:update-block-after-select into main
Reviewed-on: https://codeberg.org/a-j-wood/pv/pulls/93
2024-07-17 06:36:50 +00:00
Eric A. Borisch 3fdfd07443 Improve description and comments for blocking-write() after select() 2024-07-16 23:39:15 -05:00
Andrew Wood d801cdd722 Remove spurious strerror() call from debug report. 2024-07-16 22:44:10 +01:00
Andrew Wood 72e5078ce9 Move the MAKE_OUTPUT_NONBLOCKING code to state.c, as it can no longer work in main.c due to accessing internal structures; but still leave it switched off by default for now. 2024-07-16 22:41:31 +01:00
Andrew Wood a7c3f3dd35 Write the error from write() to the debugging output if nwritten is <0. 2024-07-16 22:23:51 +01:00
Andrew Wood 729fc10674 News item and acknowledgement for zero write bug fix (#92). 2024-07-16 22:03:56 +01:00
Andrew Wood 12f0312b00 Move the "stop at size" option setting to before the size calculation, otherwise if the size calculation tries to override that setting, it cannot do so (#91). 2024-07-16 21:58:47 +01:00
Andrew Wood 8c0e3e9dad When checking how many bytes were written, place the constant to the left of the equality check to match the rest of the code (this avoids accidental assignment if one equals sign is accidentally written instead of two), and write the appropriate debug message depending on whether the write was interrupted or it was empty. 2024-07-16 21:54:13 +01:00
Andrew Wood c7104f0c0d Merge pull request 'src/pv/transfer.c: timer going off returns with total_written==0; which is not an error.' (#92) from eborisch/pv:write-can-return-0 into main
Reviewed-on: https://codeberg.org/a-j-wood/pv/pulls/92
2024-07-16 20:47:32 +00:00
Andrew Wood 679638beb2 More details. 2024-07-16 21:42:23 +01:00
Andrew Wood f8fc5844b1 Re-order the output file descriptor setting and the size detection to correct the problem with output block device size detection that was broken in 1.8.10 (#91). 2024-07-16 21:39:29 +01:00
eborisch d86d8cf65a Clarify state. 2024-07-16 03:57:11 +00:00
eborisch 11e5b5fe95 src/pv/transfer.c: write(2) returning 0 is not an error
This is being hit easily on FreeBSD with pv sitting in a zfs send/recv pipeline. As write(2) returning 0 is not an error, handle it similar to returning -1 with EINTR or EAGAIN: wait a bit and try again.
2024-07-15 21:36:57 +00:00
Andrew Wood 42b623e9b0 Pre-release version and datestamp updates. 2024-06-15 23:40:07 +01:00
Andrew Wood 21e65b8742 Relax the strictness of this check a little, to avoid false failures on heavily loaded systems. 2024-06-15 23:11:53 +01:00
Andrew Wood c6ac4d11be Added an example of how to list untranslated strings. 2024-06-15 23:00:12 +01:00
Andrew Wood 2d48e07139 Updated the instructions for testing translations, now that a method has been found that actually works. 2024-06-15 22:47:53 +01:00
Andrew Wood 3fee341ac2 Update the line numbers etc in the language files (from "make -C po update-po") - no actual translation changes included. 2024-06-08 22:06:08 +01:00
Andrew Wood 2bed6776e4 Truncate files written with "-o". 2024-06-08 22:02:11 +01:00
Andrew Wood 01e0290d6e More replacement of hard-coded exit status bitmask values with named constants. 2024-06-08 21:57:36 +01:00
Andrew Wood 1c61154206 Replace hard-coded exit status bitmask values with named constants. 2024-06-08 21:49:46 +01:00
Andrew Wood addf25ff16 Minor cleanups after merge. 2024-06-08 21:21:11 +01:00
Andrew Wood 578c1613d1 Merge pull request 'Add '-o' option to write to a file other than stdout' (#90) from xmort/pv:add-output-file-option into main
Reviewed-on: https://codeberg.org/a-j-wood/pv/pulls/90
2024-06-08 19:22:14 +00:00
Martin Dørum 6073445551 document the --output in the man page and help text 2024-06-08 14:31:21 +02:00
Martin Dørum 30763684b7 add -o/--output option 2024-06-08 14:31:19 +02:00
Andrew Wood ace8f44f59 Added more debugging to stdout writes. 2024-05-11 21:13:12 +01:00
Andrew Wood 98994bbeaa Correct the copyright year in the "--version" output. 2024-04-22 22:25:22 +01:00
Andrew Wood b089303505 Version update. 2024-04-21 14:20:26 +01:00
Andrew Wood 8992e98c8d Line number adjustments from "make update-po". 2024-04-21 14:18:48 +01:00
Andrew Wood 205245f269 Issue #6 had only one outstanding action which was a duplicate of #34, so it is now removed. 2024-04-21 14:00:31 +01:00
Andrew Wood b375041790 Correct issues #34, #86, #87 - progress output stopping when writing output data blocks - by adding a SIGALRM handler, since ignoring the signal prevents it from interrupting writes; and use setitimer() where available, instead of alarm(), to provide sufficient granularity to handle the case where the --interval is not a whole number of seconds. 2024-04-21 13:54:01 +01:00
Andrew Wood 3a41665302 Fix incorrect "%lf" string format. 2024-04-21 12:02:35 +01:00
Andrew Wood f6686b8188 Minor formatting changes by "indent". 2024-04-21 12:01:52 +01:00
Andrew Wood 31b43cf3c7 Formatting correction. 2024-04-21 11:32:26 +01:00
Andrew Wood e483b19c14 Formatting correction. 2024-04-21 11:31:54 +01:00
Andrew Wood 50b400a1f8 Formatting correction. 2024-04-21 11:31:26 +01:00
Andrew Wood d90dc35dd3 Formatting correction. 2024-04-21 11:30:46 +01:00
Andrew Wood b45970b3b6 Added the ENVIRONMENT section. 2024-04-21 11:27:51 +01:00
Andrew Wood a5700cc914 Reinstate the use of $TMPDIR and $TMP in cursor positioning rather than hard-coding "/tmp" (#88). 2024-04-20 21:46:23 +01:00
Andrew Wood d3c59cbff3 Minor comment formatting correction. 2024-04-20 21:31:17 +01:00
Andrew Wood 8bc1cc28d0 Check for zero-length $HOME and document the reason flawfinder's warning is being ignored. 2024-04-20 21:01:04 +01:00
Andrew Wood 1ad9c321bc Adjust copyright years. 2024-03-19 22:19:42 +00:00
Andrew Wood c9dede08d4 Adjust the decimal units flag variable name from "si" to "decimal_units" so it does not overlap with other words like "size" and "signal"; add man page entry and adjust the "-L" man page entry; and allow this flag to also change how input prefixes are processed. 2024-03-19 22:17:43 +00:00
Andrew Wood 3b721112e6 Acknowledge pull request #85. 2024-03-19 21:42:08 +00:00
Andrew Wood 0093fb8276 Merge pull request 'Support for decimal SI units' (#85) from kevinruddy/pv:si-patch into main
Reviewed-on: https://codeberg.org/a-j-wood/pv/pulls/85
2024-03-19 21:30:01 +00:00
kevinruddy fe8137521a Support for decimal SI units 2024-03-19 16:57:57 -04:00
Andrew Wood 2bc7a1bb10 Added #83. 2024-03-13 21:56:34 +00:00
Andrew Wood 120ba0ba9a Minor typo correction. 2024-03-13 21:48:57 +00:00
Andrew Wood 88d93737aa Merge pull request 'Update to po/fr.po' (#83) from tbertels/pv:tbertels-patch-1 into main
Reviewed-on: https://codeberg.org/a-j-wood/pv/pulls/83
2024-03-13 21:44:46 +00:00
tbertels 317d5a3aba Update to po/fr.po
Missing strings and corrections
2024-03-12 07:31:42 +00:00
Andrew Wood ddc5cb0224 Added TODO #81. 2024-01-08 23:42:31 +00:00
35 changed files with 1238 additions and 795 deletions
+1 -1
View File
@@ -33,7 +33,7 @@ development tools. You can then run "`autoreconf -is`" to generate the
# Copyright, bug reporting, and acknowledgements
Copyright (C) 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood.
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>.
+3 -2
View File
@@ -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.8.12], [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,7 @@ 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_HEADERS([getopt.h])
AC_CHECK_HEADERS([limits.h])
AC_CHECK_HEADERS([wctype.h])
+5
View File
@@ -89,5 +89,10 @@ is acknowledged and greatly appreciated:
* 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))
---
+27 -7
View File
@@ -73,21 +73,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`".
@@ -119,6 +138,7 @@ The package maintainer should run through these steps for a new release:
* 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:
+17 -1
View File
@@ -1,3 +1,19 @@
### 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))
@@ -61,7 +77,7 @@
* 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
+6 -3
View File
@@ -2,7 +2,6 @@ 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)
@@ -11,7 +10,6 @@ Things still to do. (#n) indicates the issue tracker number.
* ([#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)
@@ -22,9 +20,14 @@ Things still to do. (#n) indicates the issue tracker number.
* ([#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)
* ([#52](https://codeberg.org/a-j-wood/pv/issues/52)) Strange race condition that affects --wait when writing to GnuPG ([danielyli](https://github.com/danielyli))
* ([#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))
* ([#59](https://codeberg.org/a-j-wood/pv/issues/59)) Slow transfer under termux but faster if strace is used ([lateautumn233](https://github.com/lateautumn233))
* ([#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
* ([#81](https://codeberg.org/a-j-wood/pv/issues/81)) Keep last output on terminal when "`pv -d`" is done ([KimHansen](https://codeberg.org/KimHansen))
* ([#84](https://codeberg.org/a-j-wood/pv/issues/84)) Allow using "`--size`" with "`--watchfd`" to show total progress of a process ([tbertels](https://codeberg.org/tbertels))
* ([#87](https://codeberg.org/a-j-wood/pv/issues/87)) Inconsistent buffer filling when writes are stuck, particularly on Cygwin ([basinilya](https://codeberg.org/basinilya))
* ([#89](https://codeberg.org/a-j-wood/pv/issues/89)) Intermittent terminal settings reset failures after multi PV pipeline completes ([stdedos](https://codeberg.org/stdedos))
Any assistance would be appreciated.
+52 -3
View File
@@ -1,4 +1,4 @@
.TH PV 1 "November 2023" Linux "User Manuals"
.TH PV 1 "July 2024" Linux "User Manuals"
.SH NAME
pv \- monitor the progress of data through a pipe
.SH SYNOPSIS
@@ -154,6 +154,11 @@ data transferred so far.
Display the total bits instead of the total bytes. The output suffix will
be "b" instead of "B".
.TP
.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.
.TP
.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
@@ -339,11 +344,21 @@ invocations in a single, long, pipeline.
.SH DATA TRANSFER MODIFIERS
.TP
.BI \-o\ FILE \fR,\ \fB\-\-output\ FILE
Write data to
.I FILE
rather than standard output. If the file already exists, it will be
truncated.
.TP
.BI \-L\ RATE \fR,\ \fB\-\-rate-limit\ RATE
Limit the transfer to a maximum of
.I RATE
bytes per second. A suffix of "K", "M", "G", or "T" can be added to denote
kibibytes (*1024), mebibytes, and so on.
kibibytes (*1024), mebibytes, and so on. If
.B \-\-si
was also passed, suffixes will denote kilobytes (*1000), megabytes, etc.
Note the caveat about the positioning of
.B \-\-si .
.TP
.BI \-B\ BYTES \fR,\ \fB\-\-buffer-size\ BYTES
Use a transfer buffer size of
@@ -654,6 +669,40 @@ Memory allocation failed.
A zero exit status indicates no problems.
.SH ENVIRONMENT
The following environment variables may affect
.BR pv :
.TP
.B HOME
The current user's home directory. This may be used by the remote control
mechanism
(the
.B \-\-remote
option)
to exchange messages between
.B pv
instances: if the
.I /run/user/UID/
directory does not exist (where
.I UID
is the current user ID), then
.I $HOME/.pv/
will be used instead.
.TP
.BR TMPDIR ", " TMP
The directory to create per-tty lock files for the terminal when using the
.B \-\-cursor
option. If
.B TMPDIR
is set to a non-empty value, it is the directory under which lock files are
created. Otherwise, if
.B TMP
is set, then it is used; and if neither are set, then
.I /tmp
is used.
.SH AUTHOR
Written by Andrew Wood, with patches submitted by various other people.
Please see the package's ACKNOWLEDGEMENTS file for a complete list of
@@ -716,7 +765,7 @@ home page: <https://www.ivarch.com/programs/pv.shtml>
.BR O_DIRECT )
.SH COPYRIGHT
Copyright \(co 2002-2008, 2010, 2012-2015, 2017, 2021, 2023 Andrew Wood.
Copyright \(co 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>.
+39 -5
View File
@@ -34,9 +34,9 @@ the expected size to **pv**:
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 \\**\
> **(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:
@@ -121,6 +121,12 @@ that are explicitly switched on will be shown.
: Display the total bits instead of the total bytes. 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.
**-T, \--buffer-percent**
: Turn on the transfer buffer percentage display. This will show the
@@ -251,11 +257,18 @@ that are explicitly switched on will be shown.
# DATA TRANSFER MODIFIERS
**-o FILE, \--output FILE**
: Write data to *FILE* rather than 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.
(\*1024), mebibytes, and so on. If **\--si** was also passed,
suffixes will denote kilobytes (\*1000), megabytes, etc. Note the
caveat about the positioning of **\--si .**
**-B BYTES, \--buffer-size BYTES**
@@ -496,6 +509,26 @@ Any other exit status is a bitmask of the following:
A zero exit status indicates no problems.
# ENVIRONMENT
The following environment variables may affect **pv**:
**HOME**
: The current user\'s home directory. This may be used by the remote
control mechanism (the **\--remote** option) 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.
**TMPDIR**, **TMP**
: The directory to create per-tty lock files for the terminal when
using the **\--cursor** option. If **TMPDIR** is set to a non-empty
value, it is the directory under which lock files are created.
Otherwise, if **TMP** is set, then it is used; and if neither are
set, then */tmp* is used.
# AUTHOR
Written by Andrew Wood, with patches submitted by various other people.
@@ -535,7 +568,8 @@ Alternatively, use the issue tracker linked from the **pv** home page:
# 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\>.
+149 -137
View File
@@ -1,7 +1,7 @@
msgid ""
msgstr ""
"Report-Msgid-Bugs-To: pv@ivarch.com\n"
"POT-Creation-Date: 2023-11-19 14:19+0000\n"
"POT-Creation-Date: 2024-07-18 22:11+0100\n"
"Language: de\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Date: 1999-06-01 15:18:29+0100\n"
@@ -44,7 +44,7 @@ msgstr "zeige die Datentransferrate an"
msgid "show data transfer average rate counter"
msgstr ""
#: src/main/help.c:301 src/main/help.c:329 src/main/help.c:341
#: src/main/help.c:301 src/main/help.c:332 src/main/help.c:344
msgid "SEC"
msgstr ""
@@ -61,234 +61,242 @@ 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
msgid "NUM"
msgid "treat suffixes as multiples of 1000 rather than 1024"
msgstr ""
#: src/main/help.c:314
msgid "show NUM bytes last written"
msgstr "NUM zeige die zuletzt geschriebenen NUM Bytes"
msgid "show percentage of transfer buffer in use"
msgstr "zeige, wie viel Prozent des Übertragungsbuffers in Benutzung sind"
#: src/main/help.c:316
msgid "FORMAT"
msgid "NUM"
msgstr ""
#: src/main/help.c:317
msgid "show NUM bytes last written"
msgstr "NUM zeige die zuletzt geschriebenen NUM Bytes"
#: src/main/help.c:319
msgid "FORMAT"
msgstr ""
#: src/main/help.c:320
msgid "set output format to FORMAT"
msgstr "setze das Ausgabeformat auf FORMAT"
#: src/main/help.c:320
#: src/main/help.c:323
msgid "output percentages, not visual information"
msgstr "Ausgabe von Prozent-Angaben statt visueller Darstellung"
#: src/main/help.c:323
#: src/main/help.c:326
msgid "do not output any transfer information at all"
msgstr "sämtliche Transferinformationen unterdrücken"
#: src/main/help.c:327
#: src/main/help.c:330
msgid "display nothing until first byte transferred"
msgstr "keine Ausgabe bevor das erste Byte übertragen wurde"
#: src/main/help.c:330
#: src/main/help.c:333
msgid "display nothing until SEC seconds have passed"
msgstr "SEC nichts anzeigen, bis SEC Sekunden vergangen sind"
#: src/main/help.c:332
#: src/main/help.c:335
msgid "SIZE"
msgstr ""
#: src/main/help.c:333
#: src/main/help.c:336
msgid "set estimated data size to SIZE bytes"
msgstr "setze erwartete Datenlänge auf SIZE Byte"
#: src/main/help.c:336
#: 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
#: src/main/help.c:345
msgid "update every SEC seconds"
msgstr "aktualisiere Ausgabe nach SEC Sekunden Intervall"
#: src/main/help.c:344
#: src/main/help.c:347
msgid "WIDTH"
msgstr ""
#: src/main/help.c:345
#: src/main/help.c:348
msgid "assume terminal is WIDTH characters wide"
msgstr "setze Terminal-Breite auf WIDTH Zeichen"
#: src/main/help.c:347
#: src/main/help.c:350
msgid "HEIGHT"
msgstr ""
#: src/main/help.c:348
#: src/main/help.c:351
msgid "assume terminal is HEIGHT rows high"
msgstr "setze Terminal-Höhe auf HEIGHT Zeichen"
#: src/main/help.c:350
#: src/main/help.c:353
msgid "NAME"
msgstr ""
#: src/main/help.c:351
#: src/main/help.c:354
msgid "prefix visual information with NAME"
msgstr "setze den NAMEn für visuelle Darstellung"
#: src/main/help.c:354
#: src/main/help.c:357
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:360
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:361
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
msgid "BYTES"
msgstr ""
#: src/main/help.c:364
msgid "use a buffer size of BYTES"
msgstr "BYTES benutze einen Puffer in der Größe von BYTES"
#: src/main/help.c:367
msgid "never use splice(), always use read/write"
msgstr "anstelle von splice() immer read/write benutzen"
#: src/main/help.c:370
msgid "skip read errors in input"
msgstr "Lesefehler in der Eingabe nicht beachten"
#: 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 "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
#: src/main/help.c:363 src/main/help.c:399 src/main/help.c:414
msgid "FILE"
msgstr ""
#: src/main/help.c:364
msgid "write output to FILE instead of stdout"
msgstr ""
#: src/main/help.c:366
msgid "RATE"
msgstr ""
#: src/main/help.c:367
msgid "limit transfer to RATE bytes per second"
msgstr "beschränke die Transferrate auf RATE Byte pro Sekunde"
#: src/main/help.c:369 src/main/help.c:378
msgid "BYTES"
msgstr ""
#: src/main/help.c:370
msgid "use a buffer size of BYTES"
msgstr "BYTES benutze einen Puffer in der Größe von BYTES"
#: src/main/help.c:373
msgid "never use splice(), always use read/write"
msgstr "anstelle von splice() immer read/write benutzen"
#: src/main/help.c:376
msgid "skip read errors in input"
msgstr "Lesefehler in der Eingabe nicht beachten"
#: src/main/help.c:379
msgid "skip errors in BYTES blocks at a time"
msgstr ""
#: src/main/help.c:382
msgid "stop after --size bytes have been transferred"
msgstr "anhalten, nachdem --size Bytes übertragen wurden"
#: src/main/help.c:385
msgid "flush cache to disk after every write"
msgstr ""
#: src/main/help.c:388
msgid "use direct I/O to bypass cache"
msgstr ""
#: src/main/help.c:391
msgid "discard input instead of writing to output"
msgstr ""
#: src/main/help.c:394
msgid "PID"
msgstr ""
#: src/main/help.c:395
msgid "update settings of process PID"
msgstr "Einstellungen der Prozess-PID updaten"
#: src/main/help.c:400
msgid "save process ID in FILE"
msgstr "Prozess-ID in FILE speichern"
#: src/main/help.c:397
#: src/main/help.c:403
msgid "PID[:FD]"
msgstr ""
#: src/main/help.c:398
#: src/main/help.c:404
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:408
msgid "show this help and exit"
msgstr "zeige diese Hilfe und beende"
#: src/main/help.c:405
#: src/main/help.c:411
msgid "show version information and exit"
msgstr "zeige Versionsinformationen und beende"
#: src/main/help.c:409
#: src/main/help.c:415
msgid "write debug logs to FILE"
msgstr ""
#: src/main/help.c:434
#: src/main/help.c:440
#, c-format
msgid "Usage: %s [OPTION] [FILE]..."
msgstr "Syntax: %s [OPTION] [DATEI]..."
#: src/main/help.c:445
#: src/main/help.c:451
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:588
#, 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:71
msgid "state allocation failed"
msgstr "Zustandszuweisung fehlgeschlagen"
#: src/main/options.c:173
#: src/main/options.c:177
msgid "option structure allocation failed"
msgstr "`option' konnte nicht allokiert werden"
#: src/main/options.c:192
#: src/main/options.c:196
msgid "option structure argv allocation failed"
msgstr "`option' (argv) konnte nicht allokiert werden"
#: src/main/options.c:254
#: src/main/options.c:258
msgid "integer argument expected"
msgstr "Ganzzahliges Argument erwartet"
#: src/main/options.c:265
#: src/main/options.c:269
msgid "numeric argument expected"
msgstr "numerisches Argument erwartet"
#: src/main/options.c:276
#: src/main/options.c:280
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:287
msgid "invalid process ID"
msgstr "ungültige Prozess-ID"
#: src/main/options.c:384 src/pv/file.c:323
#: src/main/options.c:391 src/pv/file.c:324
msgid "failed to stat file"
msgstr "Dateiinformationen konnten nicht gelesen werden"
#: src/main/options.c:487
#: src/main/options.c:502
#, 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:504
#, 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:535
msgid ""
"cannot use line mode or transfer modifier options when watching file "
"descriptors"
@@ -296,31 +304,31 @@ msgstr ""
"Beim Anzeigen von Dateideskriptoren können keine Optionen für den "
"Zeilenmodus oder den Übertragungsmodifikator verwendet werden"
#: src/main/options.c:529
#: src/main/options.c:544
msgid "cannot use cursor positioning when watching file descriptors"
msgstr ""
"Beim Anzeigen von Dateideskriptoren können keine Zeilenmodus- oder "
"Übertragungsmodifikatoroptionen verwendet werden."
#: src/main/options.c:538
#: src/main/options.c:553
msgid "cannot use remote control when watching file descriptors"
msgstr ""
"kann keine Fernbedienung verwenden, wenn Dateideskriptoren angezeigt werden"
#: src/main/options.c:547
#: src/main/options.c:562
msgid "cannot transfer files when watching file descriptors"
msgstr ""
"Dateien können beim Betrachten von Dateideskriptoren nicht übertragen werden"
#: src/main/options.c:562
#: src/main/options.c:577
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:302
msgid "message not received"
msgstr "Nachricht nicht empfangen"
#: src/main/remote.c:422
#: src/main/remote.c:429
msgid "SA_SIGINFO not supported on this system"
msgstr "SA_SIGINFO wird auf diesem System nicht unterstützt"
@@ -344,83 +352,83 @@ msgstr ""
msgid "failed to get terminal name"
msgstr "Terminalname konnte nicht gelesen werden"
#: src/pv/cursor.c:130
#: src/pv/cursor.c:132
msgid "failed to open lock file"
msgstr "Sperrdatei konnte nicht geöffnet werden"
#: src/pv/cursor.c:163
#: src/pv/cursor.c:165
msgid "lock attempt failed"
msgstr "Sperrversuch fehlgeschlagen"
#: src/pv/cursor.c:424
#: src/pv/cursor.c:426
msgid "failed to open terminal"
msgstr "Terminal konnte nicht geöffnet werden"
#: src/pv/display.c:192
#: src/pv/display.c:193
msgid "yzafpnum kMGTPEZY"
msgstr ""
#: src/pv/display.c:210
#: src/pv/display.c:211
msgid "yzafpnum KMGTPEZY"
msgstr ""
#: src/pv/display.c:746 src/pv/transfer.c:910
#: src/pv/display.c:750 src/pv/transfer.c:970
msgid "buffer allocation failed"
msgstr "Puffer konnte nicht allokiert werden"
#: src/pv/display.c:845
#: src/pv/display.c:856
msgid "b"
msgstr ""
#: src/pv/display.c:848 src/pv/transfer.c:595
#: src/pv/display.c:859 src/pv/transfer.c:602
msgid "B"
msgstr "B"
#: src/pv/display.c:890 src/pv/display.c:907
#: src/pv/display.c:900 src/pv/display.c:916
msgid "b/s"
msgstr ""
#: src/pv/display.c:895 src/pv/display.c:912
#: src/pv/display.c:905 src/pv/display.c:920
msgid "/s"
msgstr ""
#: src/pv/display.c:895 src/pv/display.c:912
#: src/pv/display.c:905 src/pv/display.c:920
msgid "B/s"
msgstr ""
#: src/pv/display.c:940 src/pv/display.c:944 src/pv/display.c:1010
#: src/pv/display.c:947 src/pv/display.c:951 src/pv/display.c:1017
msgid "ETA"
msgstr "ETA"
#: src/pv/file.c:148
#: src/pv/file.c:149
msgid "failed to seek to start of output"
msgstr "Konnte nicht versuchen, die Ausgabe zu starten"
#: src/pv/file.c:293
#: src/pv/file.c:294
msgid "failed to close file"
msgstr "Datei konnte nicht geschlossen werden"
#: src/pv/file.c:316
#: src/pv/file.c:317
msgid "failed to read file"
msgstr "Datei konnte nicht gelesen werden"
#: 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"
#: 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 ""
#: 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:575 src/pv/loop.c:626 src/pv/loop.c:667 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
@@ -428,47 +436,51 @@ msgstr ""
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:444 src/pv/state.c:455
msgid "file list allocation failed"
msgstr ""
#: 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"
#: 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:641
msgid "no transfer buffer allocated"
msgstr ""
#: src/pv/transfer.c:647
msgid "failed to set alarm signal handler"
#: src/pv/transfer.c:682
msgid "failed to set interval timer"
msgstr ""
#: src/pv/transfer.c:774
#: src/pv/transfer.c:707
msgid "failed to clear interval timer"
msgstr ""
#: src/pv/transfer.c:831
msgid "write failed"
msgstr "write-Aufruf fehlgeschlagen"
#: src/pv/transfer.c:1007
#: src/pv/transfer.c:1068
msgid "select call failed"
msgstr "select-Aufruf fehlgeschlagen"
+171 -152
View File
@@ -1,7 +1,7 @@
msgid ""
msgstr ""
"Report-Msgid-Bugs-To: pv@ivarch.com\n"
"POT-Creation-Date: 2023-11-19 14:19+0000\n"
"POT-Creation-Date: 2024-07-18 22:11+0100\n"
"Language: fr\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Date: 1999-06-01 15:18:29+0100\n"
@@ -22,272 +22,282 @@ 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
#: src/main/help.c:301 src/main/help.c:332 src/main/help.c:344
msgid "SEC"
msgstr "SEC"
#: src/main/help.c:302
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:305
msgid "show number of bytes transferred"
msgstr "affiche le nombre d'octets transférés"
msgstr "afficher le nombre d'octets transférés"
#: src/main/help.c:308
msgid "show number of bits transferred"
msgstr ""
msgstr "afficher le nombre de bits transférés"
#: 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
msgid "NUM"
msgid "treat suffixes as multiples of 1000 rather than 1024"
msgstr ""
#: src/main/help.c:314
msgid "show NUM bytes last written"
msgstr "affiche NUM octets pour la dernière fois écrits"
msgid "show percentage of transfer buffer in use"
msgstr "afficher le pourcentage de tampon de transfert utilisé"
#: src/main/help.c:316
msgid "FORMAT"
msgstr ""
msgid "NUM"
msgstr "NUM"
#: src/main/help.c:317
msgid "show NUM bytes last written"
msgstr "afficher les derniers NUM octets écrits"
#: src/main/help.c:319
msgid "FORMAT"
msgstr "FORMAT"
#: src/main/help.c:320
msgid "set output format to FORMAT"
msgstr "définir le format de sortie sur FORMAT"
#: src/main/help.c:320
msgid "output percentages, not visual information"
msgstr "imprime en pourcentage, pas les informations visuelles"
#: src/main/help.c:323
msgid "output percentages, not visual information"
msgstr "imprimer en pourcentage plutôt que des informations visuelles"
#: src/main/help.c:326
msgid "do not output any transfer information at all"
msgstr "n'afficher aucune information de transfert"
#: src/main/help.c:327
#: src/main/help.c:330
msgid "display nothing until first byte transferred"
msgstr "ne rien afficher avant qu'au moins un octet soit tranféré"
#: src/main/help.c:330
#: src/main/help.c:333
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
#: src/main/help.c:335
msgid "SIZE"
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"
#: src/main/help.c:336
msgid "count lines instead of bytes"
msgstr "compte les lignes au lieu des octets"
msgid "set estimated data size to SIZE bytes"
msgstr "ajuster la taille estimée des données à TAILLE octets"
#: 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:347
msgid "WIDTH"
msgstr "LARGEUR"
#: src/main/help.c:345
#: src/main/help.c:348
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:350
msgid "HEIGHT"
msgstr "HAUTEUR"
#: src/main/help.c:348
#: src/main/help.c:351
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:353
msgid "NAME"
msgstr "NOM"
#: src/main/help.c:351
#: src/main/help.c:354
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:357
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:360
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:363 src/main/help.c:399 src/main/help.c:414
msgid "FILE"
msgstr "FICHIER"
#: src/main/help.c:364
msgid "write output to FILE instead of stdout"
msgstr ""
#: src/main/help.c:366
msgid "RATE"
msgstr "TAUX"
#: src/main/help.c:361
#: src/main/help.c:367
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:369 src/main/help.c:378
msgid "BYTES"
msgstr "OCTETS"
#: src/main/help.c:364
#: src/main/help.c:370
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:373
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:376
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:379
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:382
msgid "stop after --size bytes have been transferred"
msgstr "arrêter après le transfert de --size octets"
#: 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 ""
msgid "flush cache to disk after every write"
msgstr "vider le cache sur le disque après chaque écriture"
#: src/main/help.c:388
msgid "use direct I/O to bypass cache"
msgstr "utiliser les E/S directes pour contourner le cache"
#: src/main/help.c:391
msgid "discard input instead of writing to output"
msgstr "rejeter l'entrée au lieu de l'écrire vers la sortie"
#: src/main/help.c:394
msgid "PID"
msgstr "PID"
#: src/main/help.c:389
#: src/main/help.c:395
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:400
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
#: src/main/help.c:403
msgid "PID[:FD]"
msgstr ""
msgstr "PID[:FD]"
#: src/main/help.c:398
#: src/main/help.c:404
msgid "watch file FD opened by process PID"
msgstr "regarder le fichier FD ouvert par le processus PID"
msgstr "surveiller le fichier FD ouvert par le processus PID"
#: src/main/help.c:402
#: src/main/help.c:408
msgid "show this help and exit"
msgstr "afficher cette aide puis quitter"
#: src/main/help.c:405
#: src/main/help.c:411
msgid "show version information and exit"
msgstr "afficher la version puis quitter"
#: src/main/help.c:409
#: src/main/help.c:415
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:440
#, c-format
msgid "Usage: %s [OPTION] [FILE]..."
msgstr "Utilisation : %s [OPTIONS] [FICHIER]..."
#: src/main/help.c:445
#: src/main/help.c:451
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:588
#, 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:71
msgid "state allocation failed"
msgstr "échec de l'allocation de mémoire de condition"
#: src/main/options.c:173
#: src/main/options.c:177
msgid "option structure allocation failed"
msgstr "l'allocation pour la structure d'une option a echoué"
msgstr "l'allocation pour la structure d'une option a échoué"
#: src/main/options.c:192
#: src/main/options.c:196
msgid "option structure argv allocation failed"
msgstr "l'allocation pour la structure de l'option argv a echoué"
msgstr "l'allocation pour la structure de l'option argv a échoué"
#: src/main/options.c:254
#: src/main/options.c:258
msgid "integer argument expected"
msgstr "Valeur entière attendue"
#: src/main/options.c:265
#: src/main/options.c:269
msgid "numeric argument expected"
msgstr "Valeur numérique attendue"
#: src/main/options.c:276
#: src/main/options.c:280
msgid "process ID or pid:fd pair expected"
msgstr "ID de processus ou paire pid:fd attendue"
#: src/main/options.c:283
#: src/main/options.c:287
msgid "invalid process ID"
msgstr "ID de processus non valide"
#: src/main/options.c:384 src/pv/file.c:323
#: src/main/options.c:391 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:502
#, 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:504
#, 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:535
msgid ""
"cannot use line mode or transfer modifier options when watching file "
"descriptors"
@@ -295,133 +305,135 @@ 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:544
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:553
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:562
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:577
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:302
msgid "message not received"
msgstr "message non reçu"
#: src/main/remote.c:422
#: src/main/remote.c:429
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
msgid "failed to get terminal name"
msgstr "échec de lecture du nom du terminal"
#: src/pv/cursor.c:130
#: src/pv/cursor.c:132
msgid "failed to open lock file"
msgstr "échec de l'ouverture du fichier de verrouillage"
#: src/pv/cursor.c:163
#: src/pv/cursor.c:165
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:426
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:193
msgid "yzafpnum kMGTPEZY"
msgstr ""
#: src/pv/display.c:210
#: src/pv/display.c:211
msgid "yzafpnum KMGTPEZY"
msgstr ""
#: src/pv/display.c:746 src/pv/transfer.c:910
#: src/pv/display.c:750 src/pv/transfer.c:970
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:856
msgid "b"
msgstr ""
#: src/pv/display.c:848 src/pv/transfer.c:595
#: src/pv/display.c:859 src/pv/transfer.c:602
msgid "B"
msgstr "O"
#: src/pv/display.c:890 src/pv/display.c:907
#: src/pv/display.c:900 src/pv/display.c:916
msgid "b/s"
msgstr ""
#: src/pv/display.c:895 src/pv/display.c:912
#: src/pv/display.c:905 src/pv/display.c:920
msgid "/s"
msgstr "/s"
#: src/pv/display.c:895 src/pv/display.c:912
#: src/pv/display.c:905 src/pv/display.c:920
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:947 src/pv/display.c:951 src/pv/display.c:1017
msgid "ETA"
msgstr "ETA"
#: src/pv/file.c:148
#: 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:575 src/pv/loop.c:626 src/pv/loop.c:667 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
@@ -429,49 +441,53 @@ msgstr ""
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:444 src/pv/state.c:455
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:641
msgid "no transfer buffer allocated"
msgstr "aucun tampon de transfert alloué"
#: src/pv/transfer.c:682
msgid "failed to set interval timer"
msgstr ""
#: src/pv/transfer.c:647
msgid "failed to set alarm signal handler"
#: src/pv/transfer.c:707
msgid "failed to clear interval timer"
msgstr ""
#: src/pv/transfer.c:774
#: src/pv/transfer.c:831
msgid "write failed"
msgstr "l'écriture a échoué"
#: src/pv/transfer.c:1007
#: src/pv/transfer.c:1068
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 +497,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"
+149 -136
View File
@@ -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-07-18 22:11+0100\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,7 +39,7 @@ msgstr "pokaż licznik prędkości przesyłania"
msgid "show data transfer average rate counter"
msgstr ""
#: src/main/help.c:301 src/main/help.c:329 src/main/help.c:341
#: src/main/help.c:301 src/main/help.c:332 src/main/help.c:344
msgid "SEC"
msgstr "WARTOŚĆ"
@@ -56,259 +56,267 @@ msgid "show number of bits transferred"
msgstr ""
#: src/main/help.c:311
msgid "show percentage of transfer buffer in use"
msgstr ""
#: src/main/help.c:313
msgid "NUM"
msgid "treat suffixes as multiples of 1000 rather than 1024"
msgstr ""
#: src/main/help.c:314
msgid "show NUM bytes last written"
msgid "show percentage of transfer buffer in use"
msgstr ""
#: src/main/help.c:316
msgid "FORMAT"
msgid "NUM"
msgstr ""
#: src/main/help.c:317
msgid "set output format to FORMAT"
msgid "show NUM bytes last written"
msgstr ""
#: src/main/help.c:319
msgid "FORMAT"
msgstr ""
#: src/main/help.c:320
msgid "set output format to FORMAT"
msgstr ""
#: src/main/help.c:323
msgid "output percentages, not visual information"
msgstr "wświetl wyjście procentowo, bez graficznej prezentacji"
#: src/main/help.c:323
#: src/main/help.c:326
msgid "do not output any transfer information at all"
msgstr "nie wyświetlaj żadnych informacji o przesyłaniu"
#: src/main/help.c:327
#: src/main/help.c:330
msgid "display nothing until first byte transferred"
msgstr "nie wyświetlaj nic aż do pierwszego przesłanego bajtu"
#: src/main/help.c:330
#: src/main/help.c:333
msgid "display nothing until SEC seconds have passed"
msgstr ""
#: src/main/help.c:332
#: src/main/help.c:335
msgid "SIZE"
msgstr "WARTOŚĆ"
#: src/main/help.c:333
#: src/main/help.c:336
msgid "set estimated data size to SIZE bytes"
msgstr "ustaw oczekiwany rozmiar danych na WARTOŚĆ bajtów"
#: src/main/help.c:336
#: src/main/help.c:339
msgid "count lines instead of bytes"
msgstr ""
#: src/main/help.c:339
#: src/main/help.c:342
msgid "lines are null-terminated"
msgstr ""
#: src/main/help.c:342
#: src/main/help.c:345
msgid "update every SEC seconds"
msgstr "aktualizuj co każde WARTOŚĆ sekund"
#: src/main/help.c:344
#: src/main/help.c:347
msgid "WIDTH"
msgstr "WARTOŚĆ"
#: src/main/help.c:345
#: src/main/help.c:348
msgid "assume terminal is WIDTH characters wide"
msgstr "przyjmij, że terminal ma szerokość WARTOŚĆ znaków"
#: src/main/help.c:347
#: src/main/help.c:350
msgid "HEIGHT"
msgstr ""
#: src/main/help.c:348
#: src/main/help.c:351
msgid "assume terminal is HEIGHT rows high"
msgstr "przyjmij, że terminal ma szerokość WARTOŚĆ znaków"
#: src/main/help.c:350
#: src/main/help.c:353
msgid "NAME"
msgstr "NAZWA"
#: src/main/help.c:351
#: src/main/help.c:354
msgid "prefix visual information with NAME"
msgstr "poprzedź informacje prefiksem NAZWA"
#: src/main/help.c:354
#: src/main/help.c:357
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
#: src/main/help.c:360
msgid "use cursor positioning escape sequences"
msgstr "używaj sekwencji escape do pozycjonowania"
#: src/main/help.c:360
msgid "RATE"
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 src/main/help.c:372
msgid "BYTES"
msgstr ""
#: src/main/help.c:364
msgid "use a buffer size of BYTES"
msgstr ""
#: 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: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 ""
#: 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 ""
#: src/main/help.c:393 src/main/help.c:408
#: src/main/help.c:363 src/main/help.c:399 src/main/help.c:414
msgid "FILE"
msgstr ""
#: src/main/help.c:364
msgid "write output to FILE instead of stdout"
msgstr ""
#: src/main/help.c:366
msgid "RATE"
msgstr ""
#: src/main/help.c:367
msgid "limit transfer to RATE bytes per second"
msgstr "ogranicz przesyłane dane do RATE bajtów na sekundę"
#: src/main/help.c:369 src/main/help.c:378
msgid "BYTES"
msgstr ""
#: src/main/help.c:370
msgid "use a buffer size of BYTES"
msgstr ""
#: src/main/help.c:373
msgid "never use splice(), always use read/write"
msgstr ""
#: src/main/help.c:376
msgid "skip read errors in input"
msgstr ""
#: src/main/help.c:379
msgid "skip errors in BYTES blocks at a time"
msgstr ""
#: src/main/help.c:382
msgid "stop after --size bytes have been transferred"
msgstr ""
#: src/main/help.c:385
msgid "flush cache to disk after every write"
msgstr ""
#: src/main/help.c:388
msgid "use direct I/O to bypass cache"
msgstr ""
#: src/main/help.c:391
msgid "discard input instead of writing to output"
msgstr ""
#: src/main/help.c:394
msgid "PID"
msgstr ""
#: src/main/help.c:395
msgid "update settings of process PID"
msgstr ""
#: src/main/help.c:400
msgid "save process ID in FILE"
msgstr ""
#: src/main/help.c:397
#: src/main/help.c:403
msgid "PID[:FD]"
msgstr ""
#: src/main/help.c:398
#: src/main/help.c:404
msgid "watch file FD opened by process PID"
msgstr ""
#: src/main/help.c:402
#: src/main/help.c:408
msgid "show this help and exit"
msgstr "wyświetl te informacje z pomocą i wyjdź"
#: src/main/help.c:405
#: src/main/help.c:411
msgid "show version information and exit"
msgstr "wyświetl informacje o wersji i wyjdź"
#: src/main/help.c:409
#: src/main/help.c:415
msgid "write debug logs to FILE"
msgstr ""
#: src/main/help.c:434
#: src/main/help.c:440
#, c-format
msgid "Usage: %s [OPTION] [FILE]..."
msgstr "Sposób użycia: %s [OPCJA] [PLIK]..."
#: src/main/help.c:445
#: src/main/help.c:451
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:588
#, 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:71
msgid "state allocation failed"
msgstr ""
#: src/main/options.c:173
#: src/main/options.c:177
msgid "option structure allocation failed"
msgstr "nie udało się zaalokować struktur opcji"
#: src/main/options.c:192
#: src/main/options.c:196
msgid "option structure argv allocation failed"
msgstr "nie udało się zaalokować struktur opcji argv"
#: src/main/options.c:254
#: src/main/options.c:258
msgid "integer argument expected"
msgstr ""
#: src/main/options.c:265
#: src/main/options.c:269
msgid "numeric argument expected"
msgstr ""
#: src/main/options.c:276
#: src/main/options.c:280
msgid "process ID or pid:fd pair expected"
msgstr ""
#: src/main/options.c:283
#: src/main/options.c:287
msgid "invalid process ID"
msgstr ""
#: src/main/options.c:384 src/pv/file.c:323
#: src/main/options.c:391 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:502
#, c-format
msgid "Try `%s --help' for more information."
msgstr "Spróbuj `%s --help' by uzyskać więcej informacji"
#: src/main/options.c:489
#: src/main/options.c:504
#, c-format
msgid "Try `%s -h' for more information."
msgstr "Spróbuj `%s -h' by uzyskać więcej informacji"
#: src/main/options.c:520
#: src/main/options.c:535
msgid ""
"cannot use line mode or transfer modifier options when watching file "
"descriptors"
msgstr ""
#: src/main/options.c:529
#: src/main/options.c:544
msgid "cannot use cursor positioning when watching file descriptors"
msgstr ""
#: src/main/options.c:538
#: src/main/options.c:553
msgid "cannot use remote control when watching file descriptors"
msgstr ""
#: src/main/options.c:547
#: src/main/options.c:562
msgid "cannot transfer files when watching file descriptors"
msgstr ""
#: src/main/options.c:562
#: src/main/options.c:577
msgid "not available on systems without /proc/self/fdinfo"
msgstr ""
#: src/main/remote.c:295
#: src/main/remote.c:302
msgid "message not received"
msgstr ""
#: src/main/remote.c:422
#: src/main/remote.c:429
msgid "SA_SIGINFO not supported on this system"
msgstr ""
@@ -333,84 +341,84 @@ msgid "failed to get terminal name"
msgstr ""
# "Przewidywany czas ukończenia" for ETA is too long
#: src/pv/cursor.c:130
#: src/pv/cursor.c:132
msgid "failed to open lock file"
msgstr ""
#: src/pv/cursor.c:163
#: src/pv/cursor.c:165
msgid "lock attempt failed"
msgstr ""
#: src/pv/cursor.c:424
#: src/pv/cursor.c:426
msgid "failed to open terminal"
msgstr "nie udało się otworzyć terminala"
#: src/pv/display.c:192
#: src/pv/display.c:193
msgid "yzafpnum kMGTPEZY"
msgstr ""
#: src/pv/display.c:210
#: src/pv/display.c:211
msgid "yzafpnum KMGTPEZY"
msgstr ""
#: src/pv/display.c:746 src/pv/transfer.c:910
#: src/pv/display.c:750 src/pv/transfer.c:970
msgid "buffer allocation failed"
msgstr "nie udało się zaalokować bufora"
#: src/pv/display.c:845
#: src/pv/display.c:856
msgid "b"
msgstr ""
#: src/pv/display.c:848 src/pv/transfer.c:595
#: src/pv/display.c:859 src/pv/transfer.c:602
msgid "B"
msgstr "B"
#: src/pv/display.c:890 src/pv/display.c:907
#: src/pv/display.c:900 src/pv/display.c:916
msgid "b/s"
msgstr ""
#: src/pv/display.c:895 src/pv/display.c:912
#: src/pv/display.c:905 src/pv/display.c:920
msgid "/s"
msgstr "/s"
#: src/pv/display.c:895 src/pv/display.c:912
#: src/pv/display.c:905 src/pv/display.c:920
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:947 src/pv/display.c:951 src/pv/display.c:1017
msgid "ETA"
msgstr "ETA"
#: src/pv/file.c:148
#: src/pv/file.c:149
msgid "failed to seek to start of output"
msgstr ""
# "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 ""
#: 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:575 src/pv/loop.c:626 src/pv/loop.c:667 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
@@ -418,47 +426,52 @@ msgstr ""
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:444 src/pv/state.c:455
msgid "file list allocation failed"
msgstr ""
#: 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 ""
#: src/pv/transfer.c:496
#: src/pv/transfer.c:503
msgid "file is not seekable"
msgstr ""
#: src/pv/transfer.c:574
#: src/pv/transfer.c:581
msgid "failed to seek past error"
msgstr ""
#: src/pv/transfer.c:594
#: src/pv/transfer.c:601
msgid "skipped past read error"
msgstr ""
#: src/pv/transfer.c:634
#: src/pv/transfer.c:641
msgid "no transfer buffer allocated"
msgstr ""
#: src/pv/transfer.c:647
msgid "failed to set alarm signal handler"
#: src/pv/transfer.c:682
msgid "failed to set interval timer"
msgstr ""
#: src/pv/transfer.c:774
# "Przewidywany czas ukończenia" for ETA is too long
#: src/pv/transfer.c:707
msgid "failed to clear interval timer"
msgstr ""
#: src/pv/transfer.c:831
msgid "write failed"
msgstr "błąd zapisu"
#: src/pv/transfer.c:1007
#: src/pv/transfer.c:1068
msgid "select call failed"
msgstr "nie udało się wywołać funkcji select"
+149 -137
View File
@@ -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-07-18 22:11+0100\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,7 +39,7 @@ 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
#: src/main/help.c:301 src/main/help.c:332 src/main/help.c:344
msgid "SEC"
msgstr ""
@@ -56,233 +56,241 @@ msgid "show number of bits transferred"
msgstr ""
#: src/main/help.c:311
msgid "show percentage of transfer buffer in use"
msgstr "exibe a porcentagem de buffer de transferência em uso"
#: src/main/help.c:313
msgid "NUM"
msgid "treat suffixes as multiples of 1000 rather than 1024"
msgstr ""
#: src/main/help.c:314
msgid "show NUM bytes last written"
msgstr "exibe NUM bytes gravados pela última vez"
msgid "show percentage of transfer buffer in use"
msgstr "exibe a porcentagem de buffer de transferência em uso"
#: src/main/help.c:316
msgid "FORMAT"
msgid "NUM"
msgstr ""
#: src/main/help.c:317
msgid "show NUM bytes last written"
msgstr "exibe NUM bytes gravados pela última vez"
#: src/main/help.c:319
msgid "FORMAT"
msgstr ""
#: src/main/help.c:320
msgid "set output format to FORMAT"
msgstr "definir o formato de saída para FORMAT"
#: src/main/help.c:320
#: src/main/help.c:323
msgid "output percentages, not visual information"
msgstr "exibe apenas as porcentagens, sem informações visuais"
#: src/main/help.c:323
#: src/main/help.c:326
msgid "do not output any transfer information at all"
msgstr "executa programa sem exibir quaisquer informações"
#: src/main/help.c:327
#: src/main/help.c:330
msgid "display nothing until first byte transferred"
msgstr "não exibe nada até iniciar o processamento"
#: src/main/help.c:330
#: src/main/help.c:333
msgid "display nothing until SEC seconds have passed"
msgstr "não exibir nada até que os segundos SEC tenham passado"
#: src/main/help.c:332
#: src/main/help.c:335
msgid "SIZE"
msgstr ""
#: src/main/help.c:333
#: src/main/help.c:336
msgid "set estimated data size to SIZE bytes"
msgstr "seta a quantidade estimada de dados em SIZE bytes"
#: src/main/help.c:336
#: 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:347
msgid "WIDTH"
msgstr ""
#: src/main/help.c:345
#: src/main/help.c:348
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:350
msgid "HEIGHT"
msgstr ""
#: src/main/help.c:348
#: src/main/help.c:351
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:353
msgid "NAME"
msgstr ""
#: src/main/help.c:351
#: src/main/help.c:354
msgid "prefix visual information with NAME"
msgstr "exibe NAME antes das demais informações"
#: src/main/help.c:354
#: src/main/help.c:357
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:360
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:363 src/main/help.c:399 src/main/help.c:414
msgid "FILE"
msgstr ""
#: src/main/help.c:364
msgid "write output to FILE instead of stdout"
msgstr ""
#: src/main/help.c:366
msgid "RATE"
msgstr ""
#: src/main/help.c:367
msgid "limit transfer to RATE bytes per second"
msgstr "limita a transferência a RATE bytes por segundo"
#: src/main/help.c:369 src/main/help.c:378
msgid "BYTES"
msgstr ""
#: src/main/help.c:370
msgid "use a buffer size of BYTES"
msgstr "use um tamanho de buffer de BYTES"
#: src/main/help.c:373
msgid "never use splice(), always use read/write"
msgstr "nunca use splice(), sempre use read/write"
#: src/main/help.c:376
msgid "skip read errors in input"
msgstr "ignorar erros de leitura em entrada"
#: src/main/help.c:379
msgid "skip errors in BYTES blocks at a time"
msgstr ""
#: src/main/help.c:382
msgid "stop after --size bytes have been transferred"
msgstr "parar após --size bytes terem sido transferidos"
#: src/main/help.c:385
msgid "flush cache to disk after every write"
msgstr ""
#: src/main/help.c:388
msgid "use direct I/O to bypass cache"
msgstr ""
#: src/main/help.c:391
msgid "discard input instead of writing to output"
msgstr ""
#: src/main/help.c:394
msgid "PID"
msgstr ""
#: src/main/help.c:395
msgid "update settings of process PID"
msgstr "atualizar as configurações do processo PID"
#: src/main/help.c:400
msgid "save process ID in FILE"
msgstr "salvar ID do processo em FILE"
#: src/main/help.c:397
#: src/main/help.c:403
msgid "PID[:FD]"
msgstr ""
#: src/main/help.c:398
#: src/main/help.c:404
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:408
msgid "show this help and exit"
msgstr "exibe esta tela de ajuda e termina"
#: src/main/help.c:405
#: src/main/help.c:411
msgid "show version information and exit"
msgstr "exibe a versão e termina"
#: src/main/help.c:409
#: src/main/help.c:415
msgid "write debug logs to FILE"
msgstr ""
#: src/main/help.c:434
#: src/main/help.c:440
#, c-format
msgid "Usage: %s [OPTION] [FILE]..."
msgstr "Uso: %s [OPÇÕES] [ARQUIVOS]..."
#: src/main/help.c:445
#: src/main/help.c:451
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:588
#, 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:71
msgid "state allocation failed"
msgstr "alocação de memória de status falhou"
#: src/main/options.c:173
#: src/main/options.c:177
msgid "option structure allocation failed"
msgstr "erro na alocação da estrutura de opções"
#: src/main/options.c:192
#: src/main/options.c:196
msgid "option structure argv allocation failed"
msgstr "erro na alocação da estrutura de opções argv"
#: src/main/options.c:254
#: src/main/options.c:258
msgid "integer argument expected"
msgstr "argumento inteiro esperado"
#: src/main/options.c:265
#: src/main/options.c:269
msgid "numeric argument expected"
msgstr "argumento numérico esperado"
#: src/main/options.c:276
#: src/main/options.c:280
msgid "process ID or pid:fd pair expected"
msgstr "ID do processo ou par pid:fd esperado"
#: src/main/options.c:283
#: src/main/options.c:287
msgid "invalid process ID"
msgstr "ID de processo inválido"
#: src/main/options.c:384 src/pv/file.c:323
#: src/main/options.c:391 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:502
#, 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:504
#, 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:535
msgid ""
"cannot use line mode or transfer modifier options when watching file "
"descriptors"
@@ -290,29 +298,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:544
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:553
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:562
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:577
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:302
msgid "message not received"
msgstr "mensagem não recebida"
#: src/main/remote.c:422
#: src/main/remote.c:429
msgid "SA_SIGINFO not supported on this system"
msgstr "SA_SIGINFO não suportado neste sistema"
@@ -336,83 +344,83 @@ msgstr ""
msgid "failed to get terminal name"
msgstr "erro ao ler o nome do terminal"
#: src/pv/cursor.c:130
#: src/pv/cursor.c:132
msgid "failed to open lock file"
msgstr "erro ao abrir arquivo de bloqueio"
#: src/pv/cursor.c:163
#: src/pv/cursor.c:165
msgid "lock attempt failed"
msgstr "tentativa de bloqueio falhou"
#: src/pv/cursor.c:424
#: src/pv/cursor.c:426
msgid "failed to open terminal"
msgstr "erro abrindo o terminal"
#: src/pv/display.c:192
#: src/pv/display.c:193
msgid "yzafpnum kMGTPEZY"
msgstr ""
#: src/pv/display.c:210
#: src/pv/display.c:211
msgid "yzafpnum KMGTPEZY"
msgstr ""
#: src/pv/display.c:746 src/pv/transfer.c:910
#: src/pv/display.c:750 src/pv/transfer.c:970
msgid "buffer allocation failed"
msgstr "erro alocando o buffer"
#: src/pv/display.c:845
#: src/pv/display.c:856
msgid "b"
msgstr ""
#: src/pv/display.c:848 src/pv/transfer.c:595
#: src/pv/display.c:859 src/pv/transfer.c:602
msgid "B"
msgstr ""
#: src/pv/display.c:890 src/pv/display.c:907
#: src/pv/display.c:900 src/pv/display.c:916
msgid "b/s"
msgstr ""
#: src/pv/display.c:895 src/pv/display.c:912
#: src/pv/display.c:905 src/pv/display.c:920
msgid "/s"
msgstr ""
#: src/pv/display.c:895 src/pv/display.c:912
#: src/pv/display.c:905 src/pv/display.c:920
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:947 src/pv/display.c:951 src/pv/display.c:1017
msgid "ETA"
msgstr "ETA"
#: src/pv/file.c:148
#: 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:575 src/pv/loop.c:626 src/pv/loop.c:667 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
@@ -420,47 +428,51 @@ msgstr ""
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:444 src/pv/state.c:455
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:641
msgid "no transfer buffer allocated"
msgstr ""
#: src/pv/transfer.c:647
msgid "failed to set alarm signal handler"
#: src/pv/transfer.c:682
msgid "failed to set interval timer"
msgstr ""
#: src/pv/transfer.c:774
#: src/pv/transfer.c:707
msgid "failed to clear interval timer"
msgstr ""
#: src/pv/transfer.c:831
msgid "write failed"
msgstr "erro de gravação"
#: src/pv/transfer.c:1007
#: src/pv/transfer.c:1068
msgid "select call failed"
msgstr "erro na chamada da função select"
+1 -1
View File
@@ -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'.
*/
+3
View File
@@ -100,6 +100,9 @@
/* 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
+4 -2
View File
@@ -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'.
*/
@@ -34,6 +34,7 @@ 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 */
@@ -53,11 +54,12 @@ struct opts_s { /* structure describing run-time options */
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 */
bool discard_input; /* set to write nothing to output */
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 */
/*@keep@*/ /*@null@*/ char *output; /* fd to write output to */
unsigned int average_rate_window; /* time window in seconds for average rate calculations */
unsigned int width; /* screen width */
unsigned int height; /* screen height */
+5 -1
View File
@@ -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'.
*/
@@ -105,6 +105,7 @@ struct pvstate_s {
bool wait; /* wait for data before display */
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 */
@@ -122,6 +123,8 @@ struct pvstate_s {
double delay_start; /* delay before first display */
pid_t watch_pid; /* process to watch fds of */
int watch_fd; /* fd to watch */
int output_fd; /* fd to write output to */
/*@null@*/ char *output_name; /* name of the output, for diagnostics */
unsigned int average_rate_window; /* time window in seconds for average rate calculations */
unsigned int width; /* screen width */
unsigned int height; /* screen height */
@@ -156,6 +159,7 @@ struct pvstate_s {
#ifdef SA_SIGINFO
struct sigaction old_sigusr2;
#endif
struct sigaction old_sigalrm;
} signal;
/*******************
+19 -4
View File
@@ -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,17 @@
extern "C" {
#endif
/*
* Exit status bitmask values.
*/
#define PV_ERROREXIT_REMOTE_OR_PID 1
#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 +60,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
@@ -164,6 +177,7 @@ extern void pv_state_wait_set(pvstate_t, bool);
extern void pv_state_delay_start_set(pvstate_t, double);
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);
@@ -183,6 +197,7 @@ 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_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 **);
+1 -1
View File
@@ -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'.
*/
+7 -1
View File
@@ -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'.
*/
@@ -307,6 +307,9 @@ void display_help(void)
{ "-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} },
{ "-T", "--buffer-percent", NULL,
N_("show percentage of transfer buffer in use"),
{ 0, 0, 0, 0} },
@@ -357,6 +360,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} },
+68 -45
View File
@@ -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>
@@ -49,8 +46,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 +70,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@ */
}
@@ -115,7 +112,7 @@ int main(int argc, char **argv)
fprintf(stderr, "%s: %s\n", opts->program_name, strerror(errno));
pv_state_free(state);
opts_free(opts);
return 1;
return PV_ERROREXIT_REMOTE_OR_PID;
}
memset(pidfile_tmp_name, 0, pidfile_tmp_bufsize);
(void) pv_snprintf(pidfile_tmp_name, pidfile_tmp_bufsize, "%s.XXXXXX", opts->pidfile);
@@ -133,7 +130,7 @@ int main(int argc, char **argv)
free(pidfile_tmp_name);
pv_state_free(state);
opts_free(opts);
return 1;
return PV_ERROREXIT_REMOTE_OR_PID;
}
(void) umask(prev_umask); /* flawfinder: ignore */
@@ -159,7 +156,7 @@ int main(int argc, char **argv)
free(pidfile_tmp_name);
pv_state_free(state);
opts_free(opts);
return 1;
return PV_ERROREXIT_REMOTE_OR_PID;
}
fprintf(pidfile_tmp_fptr, "%d\n", getpid());
@@ -183,7 +180,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 +191,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,8 +241,65 @@ 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).
*/
if (NULL == opts->output || 0 == strcmp(opts->output, "-")) {
pv_state_output_set(state, STDOUT_FILENO, "(stdout)");
} else {
int fd = open(opts->output, 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 (fd < 0) {
fprintf(stderr, "%s: %s: %s\n", opts->program_name, opts->output, strerror(errno));
pv_state_free(state);
opts_free(opts);
return PV_ERROREXIT_ACCESS;
}
pv_state_output_set(state, fd, opts->output);
}
/*
* 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) {
opts->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);
@@ -278,10 +311,10 @@ int main(int argc, char **argv)
pv_state_delay_start_set(state, opts->delay_start);
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);
@@ -299,16 +332,6 @@ int main(int argc, char **argv)
opts->fineta, 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);
+26 -11
View File
@@ -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'.
*/
@@ -44,6 +44,8 @@ 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->argv)
free(opts->argv);
/*@+keeptrans@ */
@@ -114,6 +116,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' },
@@ -142,6 +145,7 @@ opts_t opts_parse(unsigned int argc, char **argv)
{ "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 +155,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:fnqcWD:s:l0i:w:H:N:F:L:B:CEZ:SYKXR:P:d:m:o:"
#ifdef ENABLE_DEBUGGING
"!:"
#endif
@@ -335,13 +339,16 @@ 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;
@@ -387,7 +394,7 @@ opts_t opts_parse(unsigned int argc, char **argv)
/*@+mustfreefresh@ */
}
} else {
opts->size = pv_getnum_size(optarg);
opts->size = pv_getnum_size(optarg, opts->decimal_units);
}
break;
case 'l':
@@ -401,11 +408,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 +424,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 +437,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;
@@ -446,7 +453,7 @@ opts_t opts_parse(unsigned int argc, char **argv)
opts->no_splice = true;
break;
case 'R':
opts->remote = pv_getnum_count(optarg);
opts->remote = pv_getnum_count(optarg, false);
break;
case 'P':
opts->pidfile = pv_strdup(optarg);
@@ -472,8 +479,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 '!':
+15 -8
View File
@@ -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'.
*/
@@ -84,6 +84,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 +158,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;
}
/*
@@ -212,7 +219,7 @@ int pv_remote_set(opts_t opts, pvstate_t state)
control_fptr = pv__control_file(control_filename, sizeof(control_filename), getpid(), true);
if (NULL == control_fptr) {
pv_error(state, "%s", strerror(errno));
return 1;
return PV_ERROREXIT_REMOTE_OR_PID;
}
/*
@@ -223,13 +230,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 +248,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 +300,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 @ */
}
@@ -421,7 +428,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 */
+2 -2
View File
@@ -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."));
+10 -8
View File
@@ -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'.
*/
@@ -95,14 +95,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 +295,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));
+20 -13
View File
@@ -1,7 +1,7 @@
/*
* Display 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'.
*/
@@ -146,10 +146,11 @@ static long pv__seconds_remaining(const off_t so_far, const off_t total, const l
}
/*
* Types of transfer count - bytes or lines.
* Types of transfer count - bytes, decimal bytes or lines.
*/
typedef enum {
PV_TRANSFERCOUNT_BYTES,
PV_TRANSFERCOUNT_DECBYTES,
PV_TRANSFERCOUNT_LINES
} pv__transfercount_t;
@@ -346,6 +347,9 @@ static void pv__sizestr(char *buffer, size_t bufsize, char *format,
if (count_type == PV_TRANSFERCOUNT_BYTES) {
suffix = suffix_bytes;
divider = 1024.0;
} else if (count_type == PV_TRANSFERCOUNT_DECBYTES) {
suffix = suffix_bytes;
divider = 1000.0;
} else {
suffix = suffix_basic;
divider = 1000.0;
@@ -744,7 +748,7 @@ static bool pv__format(pvstate_t state, long double elapsed_sec, off_t bytes_sin
new_buffer = malloc(new_size + 16);
if (NULL == new_buffer) {
pv_error(state, "%s: %s", _("buffer allocation failed"), strerror(errno));
state->status.exit_status |= 64;
state->status.exit_status |= PV_ERROREXIT_MEMORY;
state->display.display_buffer = NULL;
return false;
}
@@ -808,6 +812,7 @@ static bool pv__format(pvstate_t state, long double elapsed_sec, off_t bytes_sin
time_t then;
struct tm *time_ptr;
char *time_format;
pv__transfercount_t count_type;
if (!state->display.component[component_type].required)
continue;
@@ -828,6 +833,12 @@ static bool pv__format(pvstate_t state, long double elapsed_sec, off_t bytes_sin
component_content[0] = '\0';
component_buf_size = PV_SIZEOF_COMPONENT_STR;
count_type = PV_TRANSFERCOUNT_BYTES;
if (state->control.linemode)
count_type = PV_TRANSFERCOUNT_LINES;
else if (state->control.decimal_units)
count_type = PV_TRANSFERCOUNT_DECBYTES;
switch (component_type) {
case PV_COMPONENT_STRING:
@@ -842,11 +853,10 @@ static bool pv__format(pvstate_t state, long double elapsed_sec, off_t bytes_sin
/*@-mustfreefresh @ */
if (state->control.bits && !state->control.linemode) {
pv__sizestr(component_content, component_buf_size, "%s",
(long double) total_bytes * 8, "", _("b"), PV_TRANSFERCOUNT_BYTES);
(long double) total_bytes * 8, "", _("b"), count_type);
} else {
pv__sizestr(component_content, component_buf_size, "%s",
(long double) total_bytes, "", _("B"),
state->control.linemode ? PV_TRANSFERCOUNT_LINES : PV_TRANSFERCOUNT_BYTES);
(long double) total_bytes, "", _("B"), count_type);
}
/*@+mustfreefresh @ */
/* splint: we trust gettext() not to really leak memory. */
@@ -888,12 +898,11 @@ static bool pv__format(pvstate_t state, long double elapsed_sec, off_t bytes_sin
if (state->control.bits && !state->control.linemode) {
/* bits per second */
pv__sizestr(component_content, component_buf_size, "[%s]", 8 * rate, "", _("b/s"),
PV_TRANSFERCOUNT_BYTES);
count_type);
} else {
/* bytes or lines per second */
pv__sizestr(component_content, component_buf_size,
"[%s]", rate, _("/s"), _("B/s"),
state->control.linemode ? PV_TRANSFERCOUNT_LINES : PV_TRANSFERCOUNT_BYTES);
"[%s]", rate, _("/s"), _("B/s"), count_type);
}
/*@+mustfreefresh @ *//* splint: see above. */
break;
@@ -904,13 +913,11 @@ static bool pv__format(pvstate_t state, long double elapsed_sec, off_t bytes_sin
if (state->control.bits && !state->control.linemode) {
/* bits per second */
pv__sizestr(component_content, component_buf_size,
"[%s]", 8 * average_rate, "", _("b/s"), PV_TRANSFERCOUNT_BYTES);
"[%s]", 8 * average_rate, "", _("b/s"), count_type);
} else {
/* bytes or lines per second */
pv__sizestr(component_content,
component_buf_size,
"[%s]", average_rate, _("/s"), _("B/s"),
state->control.linemode ? PV_TRANSFERCOUNT_LINES : PV_TRANSFERCOUNT_BYTES);
component_buf_size, "[%s]", average_rate, _("/s"), _("B/s"), count_type);
}
/*@+mustfreefresh @ *//* splint: see above. */
break;
+3 -3
View File
@@ -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@ */
+27 -26
View File
@@ -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;
}
+15 -10
View File
@@ -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'.
*/
@@ -192,6 +192,7 @@ int pv_main_loop(pvstate_t state)
&& (0 == state->control.rate_limit))) {
cansend = state->control.size - total_written;
if (0 >= cansend) {
debug("%s", "write limit reached (size explicitly set) - setting EOF flags");
eof_in = true;
eof_out = true;
}
@@ -207,6 +208,7 @@ int pv_main_loop(pvstate_t state)
/* 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;
@@ -344,6 +346,9 @@ int pv_main_loop(pvstate_t state)
transferred_since_last = 0;
}
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 {
@@ -353,7 +358,7 @@ int pv_main_loop(pvstate_t state)
}
if (1 == state->flag.trigger_exit)
state->status.exit_status |= 32;
state->status.exit_status |= PV_ERROREXIT_SIGNAL;
if (fd >= 0)
(void) close(fd);
@@ -384,7 +389,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@ */
@@ -515,7 +520,7 @@ int pv_watchfd_loop(pvstate_t state)
pv_write_retry(STDERR_FILENO, "\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 +573,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 +624,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 +665,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;
}
+39 -15
View File
@@ -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);
}
+29 -3
View File
@@ -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'.
*/
@@ -244,6 +244,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.
*/
@@ -273,8 +289,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));
@@ -360,6 +376,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));
}
@@ -389,6 +414,7 @@ void pv_sig_fini( /*@unused@ */ __attribute__((unused)) pvstate_t state)
#ifdef SA_SIGINFO
(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;
+59 -1
View File
@@ -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,11 +10,15 @@
#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 */
@@ -67,6 +71,7 @@ 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;
@@ -106,6 +111,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;
@@ -234,6 +259,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;
@@ -342,6 +372,34 @@ 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)
+1 -1
View File
@@ -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'.
*/
+109 -48
View File
@@ -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).
*
@@ -632,7 +639,7 @@ static int pv__transfer_write(pvstate_t state, bool *eof_in, bool *eof_out, long
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;
@@ -643,26 +650,71 @@ static int pv__transfer_write(pvstate_t state, bool *eof_in, bool *eof_out, long
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) {
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.
*/
@@ -748,15 +800,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 == errno) || (EAGAIN == errno)) {
if (0 == nwritten) {
debug("%s", "attempted write blocked - waiting briefly");
} else {
debug("%s: %s", "transient write error - waiting briefly", strerror(errno));
}
(void) is_data_ready(-1, NULL, -1, NULL, 10000);
return 0;
}
@@ -772,7 +829,7 @@ static int pv__transfer_write(pvstate_t state, bool *eof_in, bool *eof_out, long
}
pv_error(state, "%s: %s", _("write failed"), strerror(errno));
state->status.exit_status |= 16;
state->status.exit_status |= PV_ERROREXIT_TRANSFER;
*eof_out = true;
state->transfer.written = -1;
@@ -794,7 +851,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 +859,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 +937,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 +965,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 +983,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 +1044,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 +1070,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 +1105,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
+1 -1
View File
@@ -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'.
*/
+6 -6
View File
@@ -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