34 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
27 changed files with 735 additions and 545 deletions
+1 -1
View File
@@ -4,7 +4,7 @@ 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.9], [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])
+3
View File
@@ -91,5 +91,8 @@ is acknowledged and greatly appreciated:
* [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:
+9
View File
@@ -1,3 +1,12 @@
### 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)
+6 -2
View File
@@ -20,10 +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
* ([#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.
+7 -1
View File
@@ -1,4 +1,4 @@
.TH PV 1 "April 2024" Linux "User Manuals"
.TH PV 1 "July 2024" Linux "User Manuals"
.SH NAME
pv \- monitor the progress of data through a pipe
.SH SYNOPSIS
@@ -344,6 +344,12 @@ 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
+5
View File
@@ -257,6 +257,11 @@ 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
+104 -100
View File
@@ -1,7 +1,7 @@
msgid ""
msgstr ""
"Report-Msgid-Bugs-To: pv@ivarch.com\n"
"POT-Creation-Date: 2024-04-21 14:15+0100\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"
@@ -153,146 +153,150 @@ msgstr ""
msgid "use cursor positioning escape sequences"
msgstr "benutze Escape-Sequenzen zur Cursor-Positionierung"
#: src/main/help.c:363
msgid "RATE"
msgstr ""
#: src/main/help.c:364
msgid "limit transfer to RATE bytes per second"
msgstr "beschränke die Transferrate auf RATE Byte pro Sekunde"
#: src/main/help.c:366 src/main/help.c:375
msgid "BYTES"
msgstr ""
#: src/main/help.c:367
msgid "use a buffer size of BYTES"
msgstr "BYTES benutze einen Puffer in der Größe von BYTES"
#: src/main/help.c:370
msgid "never use splice(), always use read/write"
msgstr "anstelle von splice() immer read/write benutzen"
#: src/main/help.c:373
msgid "skip read errors in input"
msgstr "Lesefehler in der Eingabe nicht beachten"
#: src/main/help.c:376
msgid "skip errors in BYTES blocks at a time"
msgstr ""
#: src/main/help.c:379
msgid "stop after --size bytes have been transferred"
msgstr "anhalten, nachdem --size Bytes übertragen wurden"
#: src/main/help.c:382
msgid "flush cache to disk after every write"
msgstr ""
#: src/main/help.c:385
msgid "use direct I/O to bypass cache"
msgstr ""
#: src/main/help.c:388
msgid "discard input instead of writing to output"
msgstr ""
#: src/main/help.c:391
msgid "PID"
msgstr ""
#: src/main/help.c:392
msgid "update settings of process PID"
msgstr "Einstellungen der Prozess-PID updaten"
#: src/main/help.c:396 src/main/help.c:411
#: src/main/help.c:363 src/main/help.c:399 src/main/help.c:414
msgid "FILE"
msgstr ""
#: src/main/help.c:397
#: 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:400
#: src/main/help.c:403
msgid "PID[:FD]"
msgstr ""
#: src/main/help.c:401
#: 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:405
#: src/main/help.c:408
msgid "show this help and exit"
msgstr "zeige diese Hilfe und beende"
#: src/main/help.c:408
#: src/main/help.c:411
msgid "show version information and exit"
msgstr "zeige Versionsinformationen und beende"
#: src/main/help.c:412
#: src/main/help.c:415
msgid "write debug logs to FILE"
msgstr ""
#: src/main/help.c:437
#: src/main/help.c:440
#, c-format
msgid "Usage: %s [OPTION] [FILE]..."
msgstr "Syntax: %s [OPTION] [DATEI]..."
#: src/main/help.c:448
#: 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:585
#: 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:174
#: src/main/options.c:177
msgid "option structure allocation failed"
msgstr "`option' konnte nicht allokiert werden"
#: src/main/options.c:193
#: src/main/options.c:196
msgid "option structure argv allocation failed"
msgstr "`option' (argv) konnte nicht allokiert werden"
#: src/main/options.c:255
#: src/main/options.c:258
msgid "integer argument expected"
msgstr "Ganzzahliges Argument erwartet"
#: src/main/options.c:266
#: src/main/options.c:269
msgid "numeric argument expected"
msgstr "numerisches Argument erwartet"
#: src/main/options.c:277
#: 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:284
#: src/main/options.c:287
msgid "invalid process ID"
msgstr "ungültige Prozess-ID"
#: src/main/options.c:388 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:491
#: 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:493
#: 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:524
#: src/main/options.c:535
msgid ""
"cannot use line mode or transfer modifier options when watching file "
"descriptors"
@@ -300,23 +304,23 @@ msgstr ""
"Beim Anzeigen von Dateideskriptoren können keine Optionen für den "
"Zeilenmodus oder den Übertragungsmodifikator verwendet werden"
#: src/main/options.c:533
#: 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:542
#: 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:551
#: 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:566
#: src/main/options.c:577
msgid "not available on systems without /proc/self/fdinfo"
msgstr "Nicht verfügbar auf Systemen ohne /proc/self/fdinfo"
@@ -368,7 +372,7 @@ msgstr ""
msgid "yzafpnum KMGTPEZY"
msgstr ""
#: src/pv/display.c:750 src/pv/transfer.c:954
#: src/pv/display.c:750 src/pv/transfer.c:970
msgid "buffer allocation failed"
msgstr "Puffer konnte nicht allokiert werden"
@@ -376,7 +380,7 @@ msgstr "Puffer konnte nicht allokiert werden"
msgid "b"
msgstr ""
#: src/pv/display.c:859 src/pv/transfer.c:596
#: src/pv/display.c:859 src/pv/transfer.c:602
msgid "B"
msgstr "B"
@@ -396,35 +400,35 @@ msgstr ""
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
@@ -432,51 +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:391 src/pv/state.c:402
#: src/pv/state.c:444 src/pv/state.c:455
msgid "file list allocation failed"
msgstr ""
#: src/pv/transfer.c:458
#: src/pv/transfer.c:464
msgid "read failed"
msgstr "read-Aufruf fehlgeschlagen"
#: src/pv/transfer.c:481
#: src/pv/transfer.c:487
msgid "warning: read errors detected"
msgstr "warnung: lesefehler erkannt"
#: src/pv/transfer.c:497
#: src/pv/transfer.c:503
msgid "file is not seekable"
msgstr "datei ist nicht durchsuchbar"
#: src/pv/transfer.c:575
#: src/pv/transfer.c:581
msgid "failed to seek past error"
msgstr "konnte den Fehler nicht überwinden"
#: src/pv/transfer.c:595
#: src/pv/transfer.c:601
msgid "skipped past read error"
msgstr "über den Lesefehler hinaus verschoben"
#: src/pv/transfer.c:635
#: src/pv/transfer.c:641
msgid "no transfer buffer allocated"
msgstr ""
#: src/pv/transfer.c:676
#: src/pv/transfer.c:682
msgid "failed to set interval timer"
msgstr ""
#: src/pv/transfer.c:694
#: src/pv/transfer.c:707
msgid "failed to clear interval timer"
msgstr ""
#: src/pv/transfer.c:818
#: src/pv/transfer.c:831
msgid "write failed"
msgstr "write-Aufruf fehlgeschlagen"
#: src/pv/transfer.c:1051
#: src/pv/transfer.c:1068
msgid "select call failed"
msgstr "select-Aufruf fehlgeschlagen"
+104 -100
View File
@@ -1,7 +1,7 @@
msgid ""
msgstr ""
"Report-Msgid-Bugs-To: pv@ivarch.com\n"
"POT-Creation-Date: 2024-04-21 14:15+0100\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"
@@ -154,146 +154,150 @@ msgstr ""
msgid "use cursor positioning escape sequences"
msgstr "utiliser les séquences d'échappements de positionnement de curseur"
#: src/main/help.c:363
msgid "RATE"
msgstr "TAUX"
#: src/main/help.c:364
msgid "limit transfer to RATE bytes per second"
msgstr "limite le taux de transfert à TAUX octets par seconde"
#: src/main/help.c:366 src/main/help.c:375
msgid "BYTES"
msgstr "OCTETS"
#: src/main/help.c:367
msgid "use a buffer size of BYTES"
msgstr "Utiliser une mémoire tampon de OCTETS octets"
#: src/main/help.c:370
msgid "never use splice(), always use read/write"
msgstr "ne jamais utiliser splice(), toujours utiliser read/write"
#: src/main/help.c:373
msgid "skip read errors in input"
msgstr "ignorer les erreurs de lecture dans l'entrée"
#: src/main/help.c:376
msgid "skip errors in BYTES blocks at a time"
msgstr "ignorer les erreurs dans OCTETS blocs à la fois"
#: src/main/help.c:379
msgid "stop after --size bytes have been transferred"
msgstr "arrêter après le transfert de --size octets"
#: src/main/help.c:382
msgid "flush cache to disk after every write"
msgstr "vider le cache sur le disque après chaque écriture"
#: src/main/help.c:385
msgid "use direct I/O to bypass cache"
msgstr "utiliser les E/S directes pour contourner le cache"
#: src/main/help.c:388
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:391
msgid "PID"
msgstr "PID"
#: src/main/help.c:392
msgid "update settings of process PID"
msgstr "mettre à jour la configuration du processus PID"
#: src/main/help.c:396 src/main/help.c:411
#: src/main/help.c:363 src/main/help.c:399 src/main/help.c:414
msgid "FILE"
msgstr "FICHIER"
#: src/main/help.c:397
#: 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:367
msgid "limit transfer to RATE bytes per second"
msgstr "limite le taux de transfert à TAUX octets par seconde"
#: src/main/help.c:369 src/main/help.c:378
msgid "BYTES"
msgstr "OCTETS"
#: 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:373
msgid "never use splice(), always use read/write"
msgstr "ne jamais utiliser splice(), toujours utiliser read/write"
#: 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:379
msgid "skip errors in BYTES blocks at a time"
msgstr "ignorer les erreurs dans OCTETS blocs à la fois"
#: 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:385
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:395
msgid "update settings of process PID"
msgstr "mettre à jour la configuration du processus PID"
#: src/main/help.c:400
msgid "save process ID in FILE"
msgstr "enregistrer l'ID de processus dans FICHIER"
#: src/main/help.c:400
#: src/main/help.c:403
msgid "PID[:FD]"
msgstr "PID[:FD]"
#: src/main/help.c:401
#: src/main/help.c:404
msgid "watch file FD opened by process PID"
msgstr "surveiller le fichier FD ouvert par le processus PID"
#: src/main/help.c:405
#: src/main/help.c:408
msgid "show this help and exit"
msgstr "afficher cette aide puis quitter"
#: src/main/help.c:408
#: src/main/help.c:411
msgid "show version information and exit"
msgstr "afficher la version puis quitter"
#: src/main/help.c:412
#: src/main/help.c:415
msgid "write debug logs to FILE"
msgstr "écrire les journaux de déboggage vers FICHIER"
#: src/main/help.c:437
#: src/main/help.c:440
#, c-format
msgid "Usage: %s [OPTION] [FILE]..."
msgstr "Utilisation : %s [OPTIONS] [FICHIER]..."
#: src/main/help.c:448
#: src/main/help.c:451
msgid ""
"Concatenate FILE(s), or standard input, to standard output, with monitoring."
msgstr ""
"Concaténer FICHIER(s), ou l'entrée standard, sur la sortie standard avec "
"monitorage."
#: src/main/help.c:585
#: src/main/help.c:588
#, c-format
msgid "Please report any bugs to: %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:174
#: src/main/options.c:177
msgid "option structure allocation failed"
msgstr "l'allocation pour la structure d'une option a échoué"
#: src/main/options.c:193
#: src/main/options.c:196
msgid "option structure argv allocation failed"
msgstr "l'allocation pour la structure de l'option argv a échoué"
#: src/main/options.c:255
#: src/main/options.c:258
msgid "integer argument expected"
msgstr "Valeur entière attendue"
#: src/main/options.c:266
#: src/main/options.c:269
msgid "numeric argument expected"
msgstr "Valeur numérique attendue"
#: src/main/options.c:277
#: 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:284
#: src/main/options.c:287
msgid "invalid process ID"
msgstr "ID de processus non valide"
#: src/main/options.c:388 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:491
#: src/main/options.c:502
#, c-format
msgid "Try `%s --help' for more information."
msgstr "Essayez `%s --help' pour plus d'informations."
#: src/main/options.c:493
#: src/main/options.c:504
#, c-format
msgid "Try `%s -h' for more information."
msgstr "Essayez `%s -h' pour plus d'informations."
#: src/main/options.c:524
#: src/main/options.c:535
msgid ""
"cannot use line mode or transfer modifier options when watching file "
"descriptors"
@@ -301,25 +305,25 @@ 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:533
#: 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:542
#: 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:551
#: 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:566
#: 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"
@@ -373,7 +377,7 @@ msgstr ""
msgid "yzafpnum KMGTPEZY"
msgstr ""
#: src/pv/display.c:750 src/pv/transfer.c:954
#: src/pv/display.c:750 src/pv/transfer.c:970
msgid "buffer allocation failed"
msgstr "échec de l'allocation de mémoire tampon"
@@ -381,7 +385,7 @@ msgstr "échec de l'allocation de mémoire tampon"
msgid "b"
msgstr ""
#: src/pv/display.c:859 src/pv/transfer.c:596
#: src/pv/display.c:859 src/pv/transfer.c:602
msgid "B"
msgstr "O"
@@ -401,35 +405,35 @@ msgstr "O/s"
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 "(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
@@ -437,51 +441,51 @@ msgstr ""
msgid "pid"
msgstr ""
#: src/pv/state.c:36
#: src/pv/state.c:40
msgid "history structure allocation failed"
msgstr "l'allocation de la structure de l'historique a échoué"
#: src/pv/state.c:391 src/pv/state.c:402
#: src/pv/state.c:444 src/pv/state.c:455
msgid "file list allocation failed"
msgstr "échec de l'allocation de la liste de fichiers"
#: src/pv/transfer.c:458
#: src/pv/transfer.c:464
msgid "read failed"
msgstr "la lecture a échoué"
#: src/pv/transfer.c:481
#: src/pv/transfer.c:487
msgid "warning: read errors detected"
msgstr "avertissement : erreurs de lecture détectées"
#: src/pv/transfer.c:497
#: src/pv/transfer.c:503
msgid "file is not seekable"
msgstr "ne peut pas se déplacer dans le fichier"
#: src/pv/transfer.c:575
#: 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:595
#: src/pv/transfer.c:601
msgid "skipped past read error"
msgstr "erreur de lecture dépassée"
#: src/pv/transfer.c:635
#: src/pv/transfer.c:641
msgid "no transfer buffer allocated"
msgstr "aucun tampon de transfert alloué"
#: src/pv/transfer.c:676
#: src/pv/transfer.c:682
msgid "failed to set interval timer"
msgstr ""
#: src/pv/transfer.c:694
#: src/pv/transfer.c:707
msgid "failed to clear interval timer"
msgstr ""
#: src/pv/transfer.c:818
#: src/pv/transfer.c:831
msgid "write failed"
msgstr "l'écriture a échoué"
#: src/pv/transfer.c:1051
#: src/pv/transfer.c:1068
msgid "select call failed"
msgstr "l'appel de sélection a échoué"
+104 -100
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: 2024-04-21 14:15+0100\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"
@@ -147,164 +147,168 @@ msgstr "pokaż wyjście nawet gdy błędy nie są typu terminal"
msgid "use cursor positioning escape sequences"
msgstr "używaj sekwencji escape do pozycjonowania"
#: src/main/help.c:363
msgid "RATE"
msgstr ""
#: src/main/help.c:364
msgid "limit transfer to RATE bytes per second"
msgstr "ogranicz przesyłane dane do RATE bajtów na sekundę"
#: src/main/help.c:366 src/main/help.c:375
msgid "BYTES"
msgstr ""
#: src/main/help.c:367
msgid "use a buffer size of BYTES"
msgstr ""
#: src/main/help.c:370
msgid "never use splice(), always use read/write"
msgstr ""
#: src/main/help.c:373
msgid "skip read errors in input"
msgstr ""
#: src/main/help.c:376
msgid "skip errors in BYTES blocks at a time"
msgstr ""
#: src/main/help.c:379
msgid "stop after --size bytes have been transferred"
msgstr ""
#: src/main/help.c:382
msgid "flush cache to disk after every write"
msgstr ""
#: src/main/help.c:385
msgid "use direct I/O to bypass cache"
msgstr ""
#: src/main/help.c:388
msgid "discard input instead of writing to output"
msgstr ""
#: src/main/help.c:391
msgid "PID"
msgstr ""
#: src/main/help.c:392
msgid "update settings of process PID"
msgstr ""
#: src/main/help.c:396 src/main/help.c:411
#: src/main/help.c:363 src/main/help.c:399 src/main/help.c:414
msgid "FILE"
msgstr ""
#: src/main/help.c:397
msgid "save process ID in FILE"
#: 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:403
msgid "PID[:FD]"
msgstr ""
#: src/main/help.c:401
#: src/main/help.c:404
msgid "watch file FD opened by process PID"
msgstr ""
#: src/main/help.c:405
#: src/main/help.c:408
msgid "show this help and exit"
msgstr "wyświetl te informacje z pomocą i wyjdź"
#: src/main/help.c:408
#: src/main/help.c:411
msgid "show version information and exit"
msgstr "wyświetl informacje o wersji i wyjdź"
#: src/main/help.c:412
#: src/main/help.c:415
msgid "write debug logs to FILE"
msgstr ""
#: src/main/help.c:437
#: src/main/help.c:440
#, c-format
msgid "Usage: %s [OPTION] [FILE]..."
msgstr "Sposób użycia: %s [OPCJA] [PLIK]..."
#: src/main/help.c:448
#: 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:585
#: 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:174
#: src/main/options.c:177
msgid "option structure allocation failed"
msgstr "nie udało się zaalokować struktur opcji"
#: src/main/options.c:193
#: src/main/options.c:196
msgid "option structure argv allocation failed"
msgstr "nie udało się zaalokować struktur opcji argv"
#: src/main/options.c:255
#: src/main/options.c:258
msgid "integer argument expected"
msgstr ""
#: src/main/options.c:266
#: src/main/options.c:269
msgid "numeric argument expected"
msgstr ""
#: src/main/options.c:277
#: src/main/options.c:280
msgid "process ID or pid:fd pair expected"
msgstr ""
#: src/main/options.c:284
#: src/main/options.c:287
msgid "invalid process ID"
msgstr ""
#: src/main/options.c:388 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:491
#: 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:493
#: 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:524
#: src/main/options.c:535
msgid ""
"cannot use line mode or transfer modifier options when watching file "
"descriptors"
msgstr ""
#: src/main/options.c:533
#: src/main/options.c:544
msgid "cannot use cursor positioning when watching file descriptors"
msgstr ""
#: src/main/options.c:542
#: src/main/options.c:553
msgid "cannot use remote control when watching file descriptors"
msgstr ""
#: src/main/options.c:551
#: src/main/options.c:562
msgid "cannot transfer files when watching file descriptors"
msgstr ""
#: src/main/options.c:566
#: src/main/options.c:577
msgid "not available on systems without /proc/self/fdinfo"
msgstr ""
@@ -357,7 +361,7 @@ msgstr ""
msgid "yzafpnum KMGTPEZY"
msgstr ""
#: src/pv/display.c:750 src/pv/transfer.c:954
#: src/pv/display.c:750 src/pv/transfer.c:970
msgid "buffer allocation failed"
msgstr "nie udało się zaalokować bufora"
@@ -365,7 +369,7 @@ msgstr "nie udało się zaalokować bufora"
msgid "b"
msgstr ""
#: src/pv/display.c:859 src/pv/transfer.c:596
#: src/pv/display.c:859 src/pv/transfer.c:602
msgid "B"
msgstr "B"
@@ -385,36 +389,36 @@ msgstr "B/s"
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
@@ -422,52 +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:391 src/pv/state.c:402
#: src/pv/state.c:444 src/pv/state.c:455
msgid "file list allocation failed"
msgstr ""
#: src/pv/transfer.c:458
#: src/pv/transfer.c:464
msgid "read failed"
msgstr "błąd odczytu"
#: src/pv/transfer.c:481
#: src/pv/transfer.c:487
msgid "warning: read errors detected"
msgstr ""
#: src/pv/transfer.c:497
#: src/pv/transfer.c:503
msgid "file is not seekable"
msgstr ""
#: src/pv/transfer.c:575
#: src/pv/transfer.c:581
msgid "failed to seek past error"
msgstr ""
#: src/pv/transfer.c:595
#: src/pv/transfer.c:601
msgid "skipped past read error"
msgstr ""
#: src/pv/transfer.c:635
#: src/pv/transfer.c:641
msgid "no transfer buffer allocated"
msgstr ""
#: src/pv/transfer.c:676
#: src/pv/transfer.c:682
msgid "failed to set interval timer"
msgstr ""
# "Przewidywany czas ukończenia" for ETA is too long
#: src/pv/transfer.c:694
#: src/pv/transfer.c:707
msgid "failed to clear interval timer"
msgstr ""
#: src/pv/transfer.c:818
#: src/pv/transfer.c:831
msgid "write failed"
msgstr "błąd zapisu"
#: src/pv/transfer.c:1051
#: src/pv/transfer.c:1068
msgid "select call failed"
msgstr "nie udało się wywołać funkcji select"
+104 -100
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: 2024-04-21 14:15+0100\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"
@@ -147,146 +147,150 @@ msgstr "gera dados mesmo que a saída de erro seja redirecionada"
msgid "use cursor positioning escape sequences"
msgstr "utiliza caracteres de escape para posicionar o cursor"
#: src/main/help.c:363
msgid "RATE"
msgstr ""
#: src/main/help.c:364
msgid "limit transfer to RATE bytes per second"
msgstr "limita a transferência a RATE bytes por segundo"
#: src/main/help.c:366 src/main/help.c:375
msgid "BYTES"
msgstr ""
#: src/main/help.c:367
msgid "use a buffer size of BYTES"
msgstr "use um tamanho de buffer de BYTES"
#: src/main/help.c:370
msgid "never use splice(), always use read/write"
msgstr "nunca use splice(), sempre use read/write"
#: src/main/help.c:373
msgid "skip read errors in input"
msgstr "ignorar erros de leitura em entrada"
#: src/main/help.c:376
msgid "skip errors in BYTES blocks at a time"
msgstr ""
#: src/main/help.c:379
msgid "stop after --size bytes have been transferred"
msgstr "parar após --size bytes terem sido transferidos"
#: src/main/help.c:382
msgid "flush cache to disk after every write"
msgstr ""
#: src/main/help.c:385
msgid "use direct I/O to bypass cache"
msgstr ""
#: src/main/help.c:388
msgid "discard input instead of writing to output"
msgstr ""
#: src/main/help.c:391
msgid "PID"
msgstr ""
#: src/main/help.c:392
msgid "update settings of process PID"
msgstr "atualizar as configurações do processo PID"
#: src/main/help.c:396 src/main/help.c:411
#: src/main/help.c:363 src/main/help.c:399 src/main/help.c:414
msgid "FILE"
msgstr ""
#: src/main/help.c:397
#: 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:400
#: src/main/help.c:403
msgid "PID[:FD]"
msgstr ""
#: src/main/help.c:401
#: 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:405
#: src/main/help.c:408
msgid "show this help and exit"
msgstr "exibe esta tela de ajuda e termina"
#: src/main/help.c:408
#: src/main/help.c:411
msgid "show version information and exit"
msgstr "exibe a versão e termina"
#: src/main/help.c:412
#: src/main/help.c:415
msgid "write debug logs to FILE"
msgstr ""
#: src/main/help.c:437
#: src/main/help.c:440
#, c-format
msgid "Usage: %s [OPTION] [FILE]..."
msgstr "Uso: %s [OPÇÕES] [ARQUIVOS]..."
#: src/main/help.c:448
#: 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:585
#: 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:174
#: src/main/options.c:177
msgid "option structure allocation failed"
msgstr "erro na alocação da estrutura de opções"
#: src/main/options.c:193
#: 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:255
#: src/main/options.c:258
msgid "integer argument expected"
msgstr "argumento inteiro esperado"
#: src/main/options.c:266
#: src/main/options.c:269
msgid "numeric argument expected"
msgstr "argumento numérico esperado"
#: src/main/options.c:277
#: 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:284
#: src/main/options.c:287
msgid "invalid process ID"
msgstr "ID de processo inválido"
#: src/main/options.c:388 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:491
#: 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:493
#: 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:524
#: src/main/options.c:535
msgid ""
"cannot use line mode or transfer modifier options when watching file "
"descriptors"
@@ -294,21 +298,21 @@ 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:533
#: 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:542
#: 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:551
#: 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:566
#: 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"
@@ -360,7 +364,7 @@ msgstr ""
msgid "yzafpnum KMGTPEZY"
msgstr ""
#: src/pv/display.c:750 src/pv/transfer.c:954
#: src/pv/display.c:750 src/pv/transfer.c:970
msgid "buffer allocation failed"
msgstr "erro alocando o buffer"
@@ -368,7 +372,7 @@ msgstr "erro alocando o buffer"
msgid "b"
msgstr ""
#: src/pv/display.c:859 src/pv/transfer.c:596
#: src/pv/display.c:859 src/pv/transfer.c:602
msgid "B"
msgstr ""
@@ -388,35 +392,35 @@ msgstr "B/s"
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
@@ -424,51 +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:391 src/pv/state.c:402
#: src/pv/state.c:444 src/pv/state.c:455
msgid "file list allocation failed"
msgstr ""
#: src/pv/transfer.c:458
#: src/pv/transfer.c:464
msgid "read failed"
msgstr "erro de leitura"
#: src/pv/transfer.c:481
#: src/pv/transfer.c:487
msgid "warning: read errors detected"
msgstr "aviso: erros de leitura detectados"
#: src/pv/transfer.c:497
#: src/pv/transfer.c:503
msgid "file is not seekable"
msgstr "não pode mover dentro do arquivo"
#: src/pv/transfer.c:575
#: src/pv/transfer.c:581
msgid "failed to seek past error"
msgstr "não pode ir além do erro"
#: src/pv/transfer.c:595
#: src/pv/transfer.c:601
msgid "skipped past read error"
msgstr "ignorado erro de leitura"
#: src/pv/transfer.c:635
#: src/pv/transfer.c:641
msgid "no transfer buffer allocated"
msgstr ""
#: src/pv/transfer.c:676
#: src/pv/transfer.c:682
msgid "failed to set interval timer"
msgstr ""
#: src/pv/transfer.c:694
#: src/pv/transfer.c:707
msgid "failed to clear interval timer"
msgstr ""
#: src/pv/transfer.c:818
#: src/pv/transfer.c:831
msgid "write failed"
msgstr "erro de gravação"
#: src/pv/transfer.c:1051
#: src/pv/transfer.c:1068
msgid "select call failed"
msgstr "erro na chamada da função select"
+2 -1
View File
@@ -54,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 */
+2
View File
@@ -123,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 */
+12
View File
@@ -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.
*/
@@ -186,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 **);
+3
View File
@@ -360,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} },
+66 -44
View File
@@ -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);
@@ -282,7 +315,6 @@ int main(int argc, char **argv)
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);
@@ -300,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);
+12 -1
View File
@@ -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@ */
@@ -143,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) '!' },
@@ -152,7 +155,7 @@ opts_t opts_parse(unsigned int argc, char **argv)
/*@+nullassign@ */
int option_index = 0;
#endif /* HAVE_GETOPT_LONG */
char *short_options = "hVpteIrab8kTA: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
@@ -476,6 +479,14 @@ 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->decimal_units);
break;
+7 -7
View File
@@ -158,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;
}
/*
@@ -219,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;
}
/*
@@ -230,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;
}
/*
@@ -248,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");
@@ -300,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 @ */
}
@@ -428,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 */
+1 -1
View File
@@ -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."));
+1 -1
View File
@@ -748,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;
}
+2 -2
View File
@@ -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@ */
+26 -25
View File
@@ -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;
}
+14 -9
View File
@@ -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;
}
+2 -2
View File
@@ -289,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));
+53
View File
@@ -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;
@@ -347,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)
+52 -35
View File
@@ -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).
*
@@ -345,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@ */
@@ -370,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;
@@ -446,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++;
/*
@@ -612,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).
*
@@ -633,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;
@@ -678,12 +684,19 @@ static int pv__transfer_write(pvstate_t state, bool *eof_in, bool *eof_out, long
#else /* ! HAVE_SETITIMER */
(void) alarm(1);
debug("%s", "setting alarm");
#endif /* HAVE_SETITIMER */
nwritten = pv__transfer_write_repeated(STDOUT_FILENO,
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;
@@ -696,17 +709,12 @@ static int pv__transfer_write(pvstate_t state, bool *eof_in, bool *eof_out, long
/*@+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.
*/
@@ -792,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;
}
@@ -816,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;
@@ -838,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;
@@ -846,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) */
@@ -924,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;
@@ -949,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;
@@ -967,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
@@ -1027,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;
@@ -1053,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;
}
@@ -1088,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
+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