New --store-and-forward option (#100), including refactoring several areas to allow PV to run in two passes, and the ability to look at the output pipe buffer utilisation to more accurately reflect the total data transferred to the receiving end, rather than just the total amount written to the output buffer.
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
### UNRELEASED
|
||||
|
||||
* feature: new "`--store-and-forward`" option to read input to a file first, then write it to the output ([#100](https://codeberg.org/a-j-wood/pv/issues/100))
|
||||
* feature: new "`--stats`" option to show transfer stats at the end, like "`ping`" ([#49](https://codeberg.org/a-j-wood/pv/issues/49))
|
||||
* feature: "`--rate`" can now be used with "`--numeric`" ([#17](https://codeberg.org/a-j-wood/pv/issues/17))
|
||||
* feature: "`--gauge`" with "`--progress`" to show rate gauge when size is unknown ([#46](https://codeberg.org/a-j-wood/pv/issues/46))
|
||||
|
||||
@@ -491,6 +491,30 @@ except that
|
||||
is never called. Implies
|
||||
.BR \-C .
|
||||
.TP
|
||||
.BI \-U\ FILE \fR,\ \fB\-\-store\-and\-forward\ FILE
|
||||
Instead of passing data through immediately, do it in two stages - first
|
||||
read all input and write it to
|
||||
.IR FILE ,
|
||||
and then once the input is exhausted, read all of
|
||||
.I FILE
|
||||
and write it to the output.
|
||||
.I FILE
|
||||
remains in place afterwards, unless it is
|
||||
"\fB-\fR", in which case
|
||||
.B pv
|
||||
creates a temporary file for this purpose, and automatically removes it
|
||||
afterwards.
|
||||
.TP
|
||||
.B ""
|
||||
This can be useful if you have a pipeline which generates data (your
|
||||
input) quickly but you don't know the size, and you wish to pass it to some
|
||||
slower process, once all of the input has been generated and you know its
|
||||
size, so you can see its progress. Note that when doing this with
|
||||
relatively small amounts of data,
|
||||
.B \-\-no-splice
|
||||
may be preferable so that pipe buffering doesn't affect the progress
|
||||
display.
|
||||
.TP
|
||||
.BI \-d\ PID\fR[\fB:\fR\fIFD\fR],\ \fB\-\-watchfd\ PID\fR[\fB:\fR\fIFD\fR]
|
||||
Instead of transferring data, watch file descriptor
|
||||
.I FD
|
||||
|
||||
@@ -364,6 +364,23 @@ display types that are explicitly switched on will be shown.
|
||||
This is equivalent to redirecting standard output to */dev/null*,
|
||||
except that **write**(2) is never called. Implies **-C**.
|
||||
|
||||
**-U FILE, \--store-and-forward FILE**
|
||||
|
||||
: Instead of passing data through immediately, do it in two stages -
|
||||
first read all input and write it to *FILE*, and then once the input
|
||||
is exhausted, read all of *FILE* and write it to the output. *FILE*
|
||||
remains in place afterwards, unless it is \"**-**\", in which case
|
||||
**pv** creates a temporary file for this purpose, and automatically
|
||||
removes it afterwards.
|
||||
|
||||
: This can be useful if you have a pipeline which generates data (your
|
||||
input) quickly but you don\'t know the size, and you wish to pass it
|
||||
to some slower process, once all of the input has been generated and
|
||||
you know its size, so you can see its progress. Note that when doing
|
||||
this with relatively small amounts of data, **\--no-splice** may be
|
||||
preferable so that pipe buffering doesn\'t affect the progress
|
||||
display.
|
||||
|
||||
**-d PID\[:FD\], \--watchfd PID\[:FD\]**
|
||||
|
||||
: Instead of transferring data, watch file descriptor *FD* of process
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Report-Msgid-Bugs-To: pv@ivarch.com\n"
|
||||
"POT-Creation-Date: 2024-10-04 22:08+0100\n"
|
||||
"POT-Creation-Date: 2024-10-05 16:04+0100\n"
|
||||
"PO-Revision-Date: 2024-09-29 11:07+0000\n"
|
||||
"Last-Translator: a-j-wood <a-j-wood@users.noreply.translate.codeberg.org>\n"
|
||||
"Language-Team: German <https://translate.codeberg.org/projects/pv/pv/de/>\n"
|
||||
@@ -169,7 +169,8 @@ msgstr ""
|
||||
msgid "use cursor positioning escape sequences"
|
||||
msgstr "benutze Escape-Sequenzen zur Cursor-Positionierung"
|
||||
|
||||
#: src/main/help.c:369 src/main/help.c:405 src/main/help.c:420
|
||||
#: src/main/help.c:369 src/main/help.c:399 src/main/help.c:408
|
||||
#: src/main/help.c:423
|
||||
msgid "FILE"
|
||||
msgstr "DATEI"
|
||||
|
||||
@@ -222,117 +223,125 @@ msgid "discard input instead of writing to output"
|
||||
msgstr "verwirf die Eingabe anstatt in die Ausgabe zu schreiben"
|
||||
|
||||
#: src/main/help.c:400
|
||||
msgid "write all input to FILE before writing to output"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:403
|
||||
msgid "PID"
|
||||
msgstr "PID"
|
||||
|
||||
#: src/main/help.c:401
|
||||
#: src/main/help.c:404
|
||||
msgid "update settings of process PID"
|
||||
msgstr "Einstellungen der Prozess-PID updaten"
|
||||
|
||||
#: src/main/help.c:406
|
||||
#: src/main/help.c:409
|
||||
msgid "save process ID in FILE"
|
||||
msgstr "Prozess-ID in DATEI speichern"
|
||||
|
||||
#: src/main/help.c:409
|
||||
#: src/main/help.c:412
|
||||
msgid "PID[:FD]"
|
||||
msgstr "PID[:FD]"
|
||||
|
||||
#: src/main/help.c:410
|
||||
#: src/main/help.c:413
|
||||
msgid "watch file FD opened by process PID"
|
||||
msgstr "die vom Prozess PID geöffnete Datei FD beobachten"
|
||||
|
||||
#: src/main/help.c:414
|
||||
#: src/main/help.c:417
|
||||
msgid "show this help and exit"
|
||||
msgstr "zeige diese Hilfe und beende"
|
||||
|
||||
#: src/main/help.c:417
|
||||
#: src/main/help.c:420
|
||||
msgid "show version information and exit"
|
||||
msgstr "zeige Versionsinformationen und beende"
|
||||
|
||||
#: src/main/help.c:421
|
||||
#: src/main/help.c:424
|
||||
msgid "write debug logs to FILE"
|
||||
msgstr "schreibe Debug-Protokolle in DATEI"
|
||||
|
||||
#: src/main/help.c:446
|
||||
#: src/main/help.c:449
|
||||
#, c-format
|
||||
msgid "Usage: %s [OPTION] [FILE]..."
|
||||
msgstr "Aufruf: %s [OPTION] [DATEI]..."
|
||||
|
||||
#: src/main/help.c:457
|
||||
#: src/main/help.c:460
|
||||
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:594
|
||||
#: src/main/help.c:597
|
||||
#, c-format
|
||||
msgid "Please report any bugs to: %s"
|
||||
msgstr "Bitte senden Sie Fehlerberichte an %s"
|
||||
|
||||
#: src/main/main.c:71
|
||||
#: src/main/main.c:214
|
||||
msgid "(input)"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/main.c:299
|
||||
msgid "state allocation failed"
|
||||
msgstr "Speicherzuweisung für `state' fehlgeschlagen"
|
||||
|
||||
#: src/main/options.c:138 src/pv/file.c:324
|
||||
#: src/main/options.c:140 src/pv/file.c:324
|
||||
msgid "failed to stat file"
|
||||
msgstr "konnte Dateiinformationen nicht lesen"
|
||||
|
||||
#: src/main/options.c:152
|
||||
#: src/main/options.c:154
|
||||
msgid "is a directory"
|
||||
msgstr "ist ein Verzeichnis"
|
||||
|
||||
#: src/main/options.c:181
|
||||
#: src/main/options.c:183
|
||||
msgid "failed to generate sysfs filename"
|
||||
msgstr "konnte Sysfs-Dateinamen nicht erzeugen"
|
||||
|
||||
#: src/main/options.c:203
|
||||
#: src/main/options.c:205
|
||||
msgid "failed to read sysfs size file"
|
||||
msgstr "konnte Größe der Sysfs-Datei nicht lesen"
|
||||
|
||||
#: src/main/options.c:223
|
||||
#: src/main/options.c:225
|
||||
msgid "failed to open block device"
|
||||
msgstr "konnte Blockgerät nicht öffnen"
|
||||
|
||||
#: src/main/options.c:233
|
||||
#: src/main/options.c:235
|
||||
msgid "failed to determine size of block device"
|
||||
msgstr "konnte Größe des Blockgeräts nicht ermitteln"
|
||||
|
||||
#: src/main/options.c:336
|
||||
#: src/main/options.c:339
|
||||
msgid "option structure allocation failed"
|
||||
msgstr "Speicherzuweisung für `option' fehlgeschlagen"
|
||||
|
||||
#: src/main/options.c:355
|
||||
#: src/main/options.c:358
|
||||
msgid "option structure argv allocation failed"
|
||||
msgstr "Speicherzuweisung für `argv' der Option fehlgeschlagen"
|
||||
|
||||
#: src/main/options.c:417
|
||||
#: src/main/options.c:420
|
||||
msgid "integer argument expected"
|
||||
msgstr "Ganzzahliges Argument erwartet"
|
||||
|
||||
#: src/main/options.c:428
|
||||
#: src/main/options.c:431
|
||||
msgid "numeric argument expected"
|
||||
msgstr "numerisches Argument erwartet"
|
||||
|
||||
#: src/main/options.c:439
|
||||
#: src/main/options.c:442
|
||||
msgid "process ID or pid:fd pair expected"
|
||||
msgstr "Prozess-ID oder PID:FD-Paar erwartet"
|
||||
|
||||
#: src/main/options.c:446
|
||||
#: src/main/options.c:449
|
||||
msgid "invalid process ID"
|
||||
msgstr "ungültige Prozess-ID"
|
||||
|
||||
#: src/main/options.c:655
|
||||
#: src/main/options.c:666
|
||||
#, c-format
|
||||
msgid "Try `%s --help' for more information."
|
||||
msgstr "`%s --help' zeigt weitere Informationen an."
|
||||
|
||||
#: src/main/options.c:657
|
||||
#: src/main/options.c:668
|
||||
#, c-format
|
||||
msgid "Try `%s -h' for more information."
|
||||
msgstr "`%s -h' zeigt weitere Informationen an."
|
||||
|
||||
#: src/main/options.c:688
|
||||
#: src/main/options.c:699
|
||||
msgid ""
|
||||
"cannot use line mode or transfer modifier options when watching file "
|
||||
"descriptors"
|
||||
@@ -340,24 +349,24 @@ msgstr ""
|
||||
"Beim Beobachten von Dateideskriptoren können keine Optionen für den "
|
||||
"Zeilenmodus oder den Übertragungsmodifikator verwendet werden"
|
||||
|
||||
#: src/main/options.c:697
|
||||
#: src/main/options.c:708
|
||||
msgid "cannot use cursor positioning when watching file descriptors"
|
||||
msgstr ""
|
||||
"Beim Beobachten von Dateideskriptoren kann Cursor-Positionierung nicht "
|
||||
"verwendet werden"
|
||||
|
||||
#: src/main/options.c:706
|
||||
#: src/main/options.c:717
|
||||
msgid "cannot use remote control when watching file descriptors"
|
||||
msgstr ""
|
||||
"Beim Beobachten von Dateideskriptoren kann die Fernbedienung nicht verwenden "
|
||||
"werden"
|
||||
|
||||
#: src/main/options.c:715
|
||||
#: src/main/options.c:726
|
||||
msgid "cannot transfer files when watching file descriptors"
|
||||
msgstr ""
|
||||
"Beim Beobachten von Dateideskriptoren können Dateien nicht übertragen werden"
|
||||
|
||||
#: src/main/options.c:730
|
||||
#: src/main/options.c:741
|
||||
msgid "not available on systems without /proc/self/fdinfo"
|
||||
msgstr "Nicht verfügbar auf Systemen ohne /proc/self/fdinfo"
|
||||
|
||||
@@ -401,45 +410,45 @@ msgstr "Sperrversuch fehlgeschlagen"
|
||||
msgid "failed to open terminal"
|
||||
msgstr "konnte Terminal nicht öffnen"
|
||||
|
||||
#: src/pv/display.c:216
|
||||
#: src/pv/display.c:230
|
||||
msgid "yzafpnum kMGTPEZY"
|
||||
msgstr "yzafpnµm kMGTPEZY"
|
||||
|
||||
#: src/pv/display.c:234
|
||||
#: src/pv/display.c:248
|
||||
msgid "yzafpnum KMGTPEZY"
|
||||
msgstr "yzafpnµm KMGTPEZY"
|
||||
|
||||
#: src/pv/display.c:661 src/pv/transfer.c:970
|
||||
#: src/pv/display.c:675 src/pv/transfer.c:970
|
||||
msgid "buffer allocation failed"
|
||||
msgstr "Speicherzuweisung für den Puffer fehlgeschlagen"
|
||||
|
||||
#: src/pv/display.c:790
|
||||
#: src/pv/display.c:804
|
||||
msgid "b"
|
||||
msgstr "b"
|
||||
|
||||
#: src/pv/display.c:793 src/pv/transfer.c:602
|
||||
#: src/pv/display.c:807 src/pv/transfer.c:602
|
||||
msgid "B"
|
||||
msgstr "B"
|
||||
|
||||
#: src/pv/display.c:837 src/pv/display.c:852 src/pv/display.c:1071
|
||||
#: src/pv/loop.c:418
|
||||
#: src/pv/display.c:851 src/pv/display.c:866 src/pv/display.c:1085
|
||||
#: src/pv/loop.c:494
|
||||
msgid "b/s"
|
||||
msgstr "b/s"
|
||||
|
||||
#: src/pv/display.c:841 src/pv/display.c:856 src/pv/display.c:1075
|
||||
#: src/pv/display.c:855 src/pv/display.c:870 src/pv/display.c:1089
|
||||
msgid "/s"
|
||||
msgstr "/s"
|
||||
|
||||
#: src/pv/display.c:841 src/pv/display.c:856 src/pv/display.c:1075
|
||||
#: src/pv/loop.c:418
|
||||
#: src/pv/display.c:855 src/pv/display.c:870 src/pv/display.c:1089
|
||||
#: src/pv/loop.c:494
|
||||
msgid "B/s"
|
||||
msgstr "B/s"
|
||||
|
||||
#: src/pv/display.c:884 src/pv/display.c:888
|
||||
#: src/pv/display.c:898 src/pv/display.c:902
|
||||
msgid "ETA"
|
||||
msgstr "ETA"
|
||||
|
||||
#: src/pv/display.c:954
|
||||
#: src/pv/display.c:968
|
||||
msgid "FIN"
|
||||
msgstr ""
|
||||
|
||||
@@ -471,15 +480,15 @@ msgstr "(keine)"
|
||||
msgid "(stdin)"
|
||||
msgstr "(stdin)"
|
||||
|
||||
#: src/pv/loop.c:417
|
||||
#: src/pv/loop.c:493
|
||||
msgid "rate min/avg/max/mdev"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/loop.c:429
|
||||
#: src/pv/loop.c:505
|
||||
msgid "rate not measured"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/loop.c:635 src/pv/loop.c:686 src/pv/loop.c:727 src/pv/watchpid.c:99
|
||||
#: src/pv/loop.c:711 src/pv/loop.c:762 src/pv/loop.c:803 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
|
||||
@@ -491,7 +500,7 @@ msgstr "pid"
|
||||
msgid "history structure allocation failed"
|
||||
msgstr "Speicherzuweisung für `history' fehlgeschlagen"
|
||||
|
||||
#: src/pv/state.c:470 src/pv/state.c:481
|
||||
#: src/pv/state.c:501 src/pv/state.c:512
|
||||
msgid "file list allocation failed"
|
||||
msgstr "Speicherzuweisung für die Dateiliste fehlgeschlagen"
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Report-Msgid-Bugs-To: pv@ivarch.com\n"
|
||||
"POT-Creation-Date: 2024-10-04 22:08+0100\n"
|
||||
"POT-Creation-Date: 2024-10-05 16:04+0100\n"
|
||||
"Language: fr\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Date: 1999-06-01 15:18:29+0100\n"
|
||||
@@ -162,7 +162,8 @@ msgstr ""
|
||||
msgid "use cursor positioning escape sequences"
|
||||
msgstr "utiliser les séquences d'échappements de positionnement de curseur"
|
||||
|
||||
#: src/main/help.c:369 src/main/help.c:405 src/main/help.c:420
|
||||
#: src/main/help.c:369 src/main/help.c:399 src/main/help.c:408
|
||||
#: src/main/help.c:423
|
||||
msgid "FILE"
|
||||
msgstr "FICHIER"
|
||||
|
||||
@@ -215,117 +216,125 @@ 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:400
|
||||
msgid "write all input to FILE before writing to output"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:403
|
||||
msgid "PID"
|
||||
msgstr "PID"
|
||||
|
||||
#: src/main/help.c:401
|
||||
#: src/main/help.c:404
|
||||
msgid "update settings of process PID"
|
||||
msgstr "mettre à jour la configuration du processus PID"
|
||||
|
||||
#: src/main/help.c:406
|
||||
#: src/main/help.c:409
|
||||
msgid "save process ID in FILE"
|
||||
msgstr "enregistrer l'ID de processus dans FICHIER"
|
||||
|
||||
#: src/main/help.c:409
|
||||
#: src/main/help.c:412
|
||||
msgid "PID[:FD]"
|
||||
msgstr "PID[:FD]"
|
||||
|
||||
#: src/main/help.c:410
|
||||
#: src/main/help.c:413
|
||||
msgid "watch file FD opened by process PID"
|
||||
msgstr "surveiller le fichier FD ouvert par le processus PID"
|
||||
|
||||
#: src/main/help.c:414
|
||||
#: src/main/help.c:417
|
||||
msgid "show this help and exit"
|
||||
msgstr "afficher cette aide puis quitter"
|
||||
|
||||
#: src/main/help.c:417
|
||||
#: src/main/help.c:420
|
||||
msgid "show version information and exit"
|
||||
msgstr "afficher la version puis quitter"
|
||||
|
||||
#: src/main/help.c:421
|
||||
#: src/main/help.c:424
|
||||
msgid "write debug logs to FILE"
|
||||
msgstr "écrire les journaux de déboggage vers FICHIER"
|
||||
|
||||
#: src/main/help.c:446
|
||||
#: src/main/help.c:449
|
||||
#, c-format
|
||||
msgid "Usage: %s [OPTION] [FILE]..."
|
||||
msgstr "Utilisation : %s [OPTIONS] [FICHIER]..."
|
||||
|
||||
#: src/main/help.c:457
|
||||
#: src/main/help.c:460
|
||||
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:594
|
||||
#: src/main/help.c:597
|
||||
#, c-format
|
||||
msgid "Please report any bugs to: %s"
|
||||
msgstr "SVP rapporter tous bogues à %s"
|
||||
|
||||
#: src/main/main.c:71
|
||||
#: src/main/main.c:214
|
||||
msgid "(input)"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/main.c:299
|
||||
msgid "state allocation failed"
|
||||
msgstr "échec de l'allocation de mémoire de condition"
|
||||
|
||||
#: src/main/options.c:138 src/pv/file.c:324
|
||||
#: src/main/options.c:140 src/pv/file.c:324
|
||||
msgid "failed to stat file"
|
||||
msgstr "échec à statuer sur le fichier"
|
||||
|
||||
#: src/main/options.c:152
|
||||
#: src/main/options.c:154
|
||||
msgid "is a directory"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:181
|
||||
#: src/main/options.c:183
|
||||
msgid "failed to generate sysfs filename"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:203
|
||||
#: src/main/options.c:205
|
||||
msgid "failed to read sysfs size file"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:223
|
||||
#: src/main/options.c:225
|
||||
msgid "failed to open block device"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:233
|
||||
#: src/main/options.c:235
|
||||
msgid "failed to determine size of block device"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:336
|
||||
#: src/main/options.c:339
|
||||
msgid "option structure allocation failed"
|
||||
msgstr "l'allocation pour la structure d'une option a échoué"
|
||||
|
||||
#: src/main/options.c:355
|
||||
#: src/main/options.c:358
|
||||
msgid "option structure argv allocation failed"
|
||||
msgstr "l'allocation pour la structure de l'option argv a échoué"
|
||||
|
||||
#: src/main/options.c:417
|
||||
#: src/main/options.c:420
|
||||
msgid "integer argument expected"
|
||||
msgstr "Valeur entière attendue"
|
||||
|
||||
#: src/main/options.c:428
|
||||
#: src/main/options.c:431
|
||||
msgid "numeric argument expected"
|
||||
msgstr "Valeur numérique attendue"
|
||||
|
||||
#: src/main/options.c:439
|
||||
#: src/main/options.c:442
|
||||
msgid "process ID or pid:fd pair expected"
|
||||
msgstr "ID de processus ou paire pid:fd attendue"
|
||||
|
||||
#: src/main/options.c:446
|
||||
#: src/main/options.c:449
|
||||
msgid "invalid process ID"
|
||||
msgstr "ID de processus non valide"
|
||||
|
||||
#: src/main/options.c:655
|
||||
#: src/main/options.c:666
|
||||
#, c-format
|
||||
msgid "Try `%s --help' for more information."
|
||||
msgstr "Essayez `%s --help' pour plus d'informations."
|
||||
|
||||
#: src/main/options.c:657
|
||||
#: src/main/options.c:668
|
||||
#, c-format
|
||||
msgid "Try `%s -h' for more information."
|
||||
msgstr "Essayez `%s -h' pour plus d'informations."
|
||||
|
||||
#: src/main/options.c:688
|
||||
#: src/main/options.c:699
|
||||
msgid ""
|
||||
"cannot use line mode or transfer modifier options when watching file "
|
||||
"descriptors"
|
||||
@@ -333,25 +342,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:697
|
||||
#: src/main/options.c:708
|
||||
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:706
|
||||
#: src/main/options.c:717
|
||||
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:715
|
||||
#: src/main/options.c:726
|
||||
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:730
|
||||
#: src/main/options.c:741
|
||||
msgid "not available on systems without /proc/self/fdinfo"
|
||||
msgstr "non disponible sur les systèmes sans /proc/self/fdinfo"
|
||||
|
||||
@@ -397,45 +406,45 @@ msgstr "échec de la tentative de verrouillage"
|
||||
msgid "failed to open terminal"
|
||||
msgstr "échec de l'ouverture du terminal"
|
||||
|
||||
#: src/pv/display.c:216
|
||||
#: src/pv/display.c:230
|
||||
msgid "yzafpnum kMGTPEZY"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:234
|
||||
#: src/pv/display.c:248
|
||||
msgid "yzafpnum KMGTPEZY"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:661 src/pv/transfer.c:970
|
||||
#: src/pv/display.c:675 src/pv/transfer.c:970
|
||||
msgid "buffer allocation failed"
|
||||
msgstr "échec de l'allocation de mémoire tampon"
|
||||
|
||||
#: src/pv/display.c:790
|
||||
#: src/pv/display.c:804
|
||||
msgid "b"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:793 src/pv/transfer.c:602
|
||||
#: src/pv/display.c:807 src/pv/transfer.c:602
|
||||
msgid "B"
|
||||
msgstr "O"
|
||||
|
||||
#: src/pv/display.c:837 src/pv/display.c:852 src/pv/display.c:1071
|
||||
#: src/pv/loop.c:418
|
||||
#: src/pv/display.c:851 src/pv/display.c:866 src/pv/display.c:1085
|
||||
#: src/pv/loop.c:494
|
||||
msgid "b/s"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:841 src/pv/display.c:856 src/pv/display.c:1075
|
||||
#: src/pv/display.c:855 src/pv/display.c:870 src/pv/display.c:1089
|
||||
msgid "/s"
|
||||
msgstr "/s"
|
||||
|
||||
#: src/pv/display.c:841 src/pv/display.c:856 src/pv/display.c:1075
|
||||
#: src/pv/loop.c:418
|
||||
#: src/pv/display.c:855 src/pv/display.c:870 src/pv/display.c:1089
|
||||
#: src/pv/loop.c:494
|
||||
msgid "B/s"
|
||||
msgstr "O/s"
|
||||
|
||||
#: src/pv/display.c:884 src/pv/display.c:888
|
||||
#: src/pv/display.c:898 src/pv/display.c:902
|
||||
msgid "ETA"
|
||||
msgstr "ETA"
|
||||
|
||||
#: src/pv/display.c:954
|
||||
#: src/pv/display.c:968
|
||||
msgid "FIN"
|
||||
msgstr ""
|
||||
|
||||
@@ -467,15 +476,15 @@ msgstr "(aucun)"
|
||||
msgid "(stdin)"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/loop.c:417
|
||||
#: src/pv/loop.c:493
|
||||
msgid "rate min/avg/max/mdev"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/loop.c:429
|
||||
#: src/pv/loop.c:505
|
||||
msgid "rate not measured"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/loop.c:635 src/pv/loop.c:686 src/pv/loop.c:727 src/pv/watchpid.c:99
|
||||
#: src/pv/loop.c:711 src/pv/loop.c:762 src/pv/loop.c:803 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
|
||||
@@ -487,7 +496,7 @@ msgstr ""
|
||||
msgid "history structure allocation failed"
|
||||
msgstr "l'allocation de la structure de l'historique a échoué"
|
||||
|
||||
#: src/pv/state.c:470 src/pv/state.c:481
|
||||
#: src/pv/state.c:501 src/pv/state.c:512
|
||||
msgid "file list allocation failed"
|
||||
msgstr "échec de l'allocation de la liste de fichiers"
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: pv@ivarch.com\n"
|
||||
"POT-Creation-Date: 2024-10-04 22:08+0100\n"
|
||||
"POT-Creation-Date: 2024-10-05 16:04+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"
|
||||
@@ -155,7 +155,8 @@ 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:369 src/main/help.c:405 src/main/help.c:420
|
||||
#: src/main/help.c:369 src/main/help.c:399 src/main/help.c:408
|
||||
#: src/main/help.c:423
|
||||
msgid "FILE"
|
||||
msgstr ""
|
||||
|
||||
@@ -208,135 +209,143 @@ msgid "discard input instead of writing to output"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:400
|
||||
msgid "write all input to FILE before writing to output"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:403
|
||||
msgid "PID"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:401
|
||||
#: src/main/help.c:404
|
||||
msgid "update settings of process PID"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:406
|
||||
#: src/main/help.c:409
|
||||
msgid "save process ID in FILE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:409
|
||||
#: src/main/help.c:412
|
||||
msgid "PID[:FD]"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:410
|
||||
#: src/main/help.c:413
|
||||
msgid "watch file FD opened by process PID"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:414
|
||||
#: src/main/help.c:417
|
||||
msgid "show this help and exit"
|
||||
msgstr "wyświetl te informacje z pomocą i wyjdź"
|
||||
|
||||
#: src/main/help.c:417
|
||||
#: src/main/help.c:420
|
||||
msgid "show version information and exit"
|
||||
msgstr "wyświetl informacje o wersji i wyjdź"
|
||||
|
||||
#: src/main/help.c:421
|
||||
#: src/main/help.c:424
|
||||
msgid "write debug logs to FILE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:446
|
||||
#: src/main/help.c:449
|
||||
#, c-format
|
||||
msgid "Usage: %s [OPTION] [FILE]..."
|
||||
msgstr "Sposób użycia: %s [OPCJA] [PLIK]..."
|
||||
|
||||
#: src/main/help.c:457
|
||||
#: src/main/help.c:460
|
||||
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:594
|
||||
#: src/main/help.c:597
|
||||
#, c-format
|
||||
msgid "Please report any bugs to: %s"
|
||||
msgstr "Proszę przesyłać zgłoszenia błędów do %s"
|
||||
|
||||
#: src/main/main.c:71
|
||||
#: src/main/main.c:214
|
||||
msgid "(input)"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/main.c:299
|
||||
msgid "state allocation failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:138 src/pv/file.c:324
|
||||
#: src/main/options.c:140 src/pv/file.c:324
|
||||
msgid "failed to stat file"
|
||||
msgstr "nie udało się wykonać operacji stat na pliku"
|
||||
|
||||
#: src/main/options.c:152
|
||||
#: src/main/options.c:154
|
||||
msgid "is a directory"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:181
|
||||
#: src/main/options.c:183
|
||||
msgid "failed to generate sysfs filename"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:203
|
||||
#: src/main/options.c:205
|
||||
msgid "failed to read sysfs size file"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:223
|
||||
#: src/main/options.c:225
|
||||
msgid "failed to open block device"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:233
|
||||
#: src/main/options.c:235
|
||||
msgid "failed to determine size of block device"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:336
|
||||
#: src/main/options.c:339
|
||||
msgid "option structure allocation failed"
|
||||
msgstr "nie udało się zaalokować struktur opcji"
|
||||
|
||||
#: src/main/options.c:355
|
||||
#: src/main/options.c:358
|
||||
msgid "option structure argv allocation failed"
|
||||
msgstr "nie udało się zaalokować struktur opcji argv"
|
||||
|
||||
#: src/main/options.c:417
|
||||
#: src/main/options.c:420
|
||||
msgid "integer argument expected"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:428
|
||||
#: src/main/options.c:431
|
||||
msgid "numeric argument expected"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:439
|
||||
#: src/main/options.c:442
|
||||
msgid "process ID or pid:fd pair expected"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:446
|
||||
#: src/main/options.c:449
|
||||
msgid "invalid process ID"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:655
|
||||
#: src/main/options.c:666
|
||||
#, c-format
|
||||
msgid "Try `%s --help' for more information."
|
||||
msgstr "Spróbuj `%s --help' by uzyskać więcej informacji"
|
||||
|
||||
#: src/main/options.c:657
|
||||
#: src/main/options.c:668
|
||||
#, c-format
|
||||
msgid "Try `%s -h' for more information."
|
||||
msgstr "Spróbuj `%s -h' by uzyskać więcej informacji"
|
||||
|
||||
#: src/main/options.c:688
|
||||
#: src/main/options.c:699
|
||||
msgid ""
|
||||
"cannot use line mode or transfer modifier options when watching file "
|
||||
"descriptors"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:697
|
||||
#: src/main/options.c:708
|
||||
msgid "cannot use cursor positioning when watching file descriptors"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:706
|
||||
#: src/main/options.c:717
|
||||
msgid "cannot use remote control when watching file descriptors"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:715
|
||||
#: src/main/options.c:726
|
||||
msgid "cannot transfer files when watching file descriptors"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:730
|
||||
#: src/main/options.c:741
|
||||
msgid "not available on systems without /proc/self/fdinfo"
|
||||
msgstr ""
|
||||
|
||||
@@ -381,45 +390,45 @@ msgstr ""
|
||||
msgid "failed to open terminal"
|
||||
msgstr "nie udało się otworzyć terminala"
|
||||
|
||||
#: src/pv/display.c:216
|
||||
#: src/pv/display.c:230
|
||||
msgid "yzafpnum kMGTPEZY"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:234
|
||||
#: src/pv/display.c:248
|
||||
msgid "yzafpnum KMGTPEZY"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:661 src/pv/transfer.c:970
|
||||
#: src/pv/display.c:675 src/pv/transfer.c:970
|
||||
msgid "buffer allocation failed"
|
||||
msgstr "nie udało się zaalokować bufora"
|
||||
|
||||
#: src/pv/display.c:790
|
||||
#: src/pv/display.c:804
|
||||
msgid "b"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:793 src/pv/transfer.c:602
|
||||
#: src/pv/display.c:807 src/pv/transfer.c:602
|
||||
msgid "B"
|
||||
msgstr "B"
|
||||
|
||||
#: src/pv/display.c:837 src/pv/display.c:852 src/pv/display.c:1071
|
||||
#: src/pv/loop.c:418
|
||||
#: src/pv/display.c:851 src/pv/display.c:866 src/pv/display.c:1085
|
||||
#: src/pv/loop.c:494
|
||||
msgid "b/s"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:841 src/pv/display.c:856 src/pv/display.c:1075
|
||||
#: src/pv/display.c:855 src/pv/display.c:870 src/pv/display.c:1089
|
||||
msgid "/s"
|
||||
msgstr "/s"
|
||||
|
||||
#: src/pv/display.c:841 src/pv/display.c:856 src/pv/display.c:1075
|
||||
#: src/pv/loop.c:418
|
||||
#: src/pv/display.c:855 src/pv/display.c:870 src/pv/display.c:1089
|
||||
#: src/pv/loop.c:494
|
||||
msgid "B/s"
|
||||
msgstr "B/s"
|
||||
|
||||
#: src/pv/display.c:884 src/pv/display.c:888
|
||||
#: src/pv/display.c:898 src/pv/display.c:902
|
||||
msgid "ETA"
|
||||
msgstr "ETA"
|
||||
|
||||
#: src/pv/display.c:954
|
||||
#: src/pv/display.c:968
|
||||
msgid "FIN"
|
||||
msgstr ""
|
||||
|
||||
@@ -452,15 +461,15 @@ msgstr ""
|
||||
msgid "(stdin)"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/loop.c:417
|
||||
#: src/pv/loop.c:493
|
||||
msgid "rate min/avg/max/mdev"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/loop.c:429
|
||||
#: src/pv/loop.c:505
|
||||
msgid "rate not measured"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/loop.c:635 src/pv/loop.c:686 src/pv/loop.c:727 src/pv/watchpid.c:99
|
||||
#: src/pv/loop.c:711 src/pv/loop.c:762 src/pv/loop.c:803 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
|
||||
@@ -472,7 +481,7 @@ msgstr ""
|
||||
msgid "history structure allocation failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/state.c:470 src/pv/state.c:481
|
||||
#: src/pv/state.c:501 src/pv/state.c:512
|
||||
msgid "file list allocation failed"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: pv@ivarch.com\n"
|
||||
"POT-Creation-Date: 2024-10-04 22:08+0100\n"
|
||||
"POT-Creation-Date: 2024-10-05 16:04+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"
|
||||
@@ -155,7 +155,8 @@ 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:369 src/main/help.c:405 src/main/help.c:420
|
||||
#: src/main/help.c:369 src/main/help.c:399 src/main/help.c:408
|
||||
#: src/main/help.c:423
|
||||
msgid "FILE"
|
||||
msgstr ""
|
||||
|
||||
@@ -208,117 +209,125 @@ msgid "discard input instead of writing to output"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:400
|
||||
msgid "write all input to FILE before writing to output"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:403
|
||||
msgid "PID"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:401
|
||||
#: src/main/help.c:404
|
||||
msgid "update settings of process PID"
|
||||
msgstr "atualizar as configurações do processo PID"
|
||||
|
||||
#: src/main/help.c:406
|
||||
#: src/main/help.c:409
|
||||
msgid "save process ID in FILE"
|
||||
msgstr "salvar ID do processo em FILE"
|
||||
|
||||
#: src/main/help.c:409
|
||||
#: src/main/help.c:412
|
||||
msgid "PID[:FD]"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:410
|
||||
#: src/main/help.c:413
|
||||
msgid "watch file FD opened by process PID"
|
||||
msgstr "assistir arquivo FD aberto pelo processo PID"
|
||||
|
||||
#: src/main/help.c:414
|
||||
#: src/main/help.c:417
|
||||
msgid "show this help and exit"
|
||||
msgstr "exibe esta tela de ajuda e termina"
|
||||
|
||||
#: src/main/help.c:417
|
||||
#: src/main/help.c:420
|
||||
msgid "show version information and exit"
|
||||
msgstr "exibe a versão e termina"
|
||||
|
||||
#: src/main/help.c:421
|
||||
#: src/main/help.c:424
|
||||
msgid "write debug logs to FILE"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/help.c:446
|
||||
#: src/main/help.c:449
|
||||
#, c-format
|
||||
msgid "Usage: %s [OPTION] [FILE]..."
|
||||
msgstr "Uso: %s [OPÇÕES] [ARQUIVOS]..."
|
||||
|
||||
#: src/main/help.c:457
|
||||
#: src/main/help.c:460
|
||||
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:594
|
||||
#: src/main/help.c:597
|
||||
#, c-format
|
||||
msgid "Please report any bugs to: %s"
|
||||
msgstr "Por favor, reporte quaisquer defeitos para %s"
|
||||
|
||||
#: src/main/main.c:71
|
||||
#: src/main/main.c:214
|
||||
msgid "(input)"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/main.c:299
|
||||
msgid "state allocation failed"
|
||||
msgstr "alocação de memória de status falhou"
|
||||
|
||||
#: src/main/options.c:138 src/pv/file.c:324
|
||||
#: src/main/options.c:140 src/pv/file.c:324
|
||||
msgid "failed to stat file"
|
||||
msgstr "erro obtendo informações do arquivo"
|
||||
|
||||
#: src/main/options.c:152
|
||||
#: src/main/options.c:154
|
||||
msgid "is a directory"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:181
|
||||
#: src/main/options.c:183
|
||||
msgid "failed to generate sysfs filename"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:203
|
||||
#: src/main/options.c:205
|
||||
msgid "failed to read sysfs size file"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:223
|
||||
#: src/main/options.c:225
|
||||
msgid "failed to open block device"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:233
|
||||
#: src/main/options.c:235
|
||||
msgid "failed to determine size of block device"
|
||||
msgstr ""
|
||||
|
||||
#: src/main/options.c:336
|
||||
#: src/main/options.c:339
|
||||
msgid "option structure allocation failed"
|
||||
msgstr "erro na alocação da estrutura de opções"
|
||||
|
||||
#: src/main/options.c:355
|
||||
#: src/main/options.c:358
|
||||
msgid "option structure argv allocation failed"
|
||||
msgstr "erro na alocação da estrutura de opções argv"
|
||||
|
||||
#: src/main/options.c:417
|
||||
#: src/main/options.c:420
|
||||
msgid "integer argument expected"
|
||||
msgstr "argumento inteiro esperado"
|
||||
|
||||
#: src/main/options.c:428
|
||||
#: src/main/options.c:431
|
||||
msgid "numeric argument expected"
|
||||
msgstr "argumento numérico esperado"
|
||||
|
||||
#: src/main/options.c:439
|
||||
#: src/main/options.c:442
|
||||
msgid "process ID or pid:fd pair expected"
|
||||
msgstr "ID do processo ou par pid:fd esperado"
|
||||
|
||||
#: src/main/options.c:446
|
||||
#: src/main/options.c:449
|
||||
msgid "invalid process ID"
|
||||
msgstr "ID de processo inválido"
|
||||
|
||||
#: src/main/options.c:655
|
||||
#: src/main/options.c:666
|
||||
#, c-format
|
||||
msgid "Try `%s --help' for more information."
|
||||
msgstr "Tente `%s --help' para maiores informações."
|
||||
|
||||
#: src/main/options.c:657
|
||||
#: src/main/options.c:668
|
||||
#, c-format
|
||||
msgid "Try `%s -h' for more information."
|
||||
msgstr "Tente `%s -h' para maiores informações."
|
||||
|
||||
#: src/main/options.c:688
|
||||
#: src/main/options.c:699
|
||||
msgid ""
|
||||
"cannot use line mode or transfer modifier options when watching file "
|
||||
"descriptors"
|
||||
@@ -326,21 +335,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:697
|
||||
#: src/main/options.c:708
|
||||
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:706
|
||||
#: src/main/options.c:717
|
||||
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:715
|
||||
#: src/main/options.c:726
|
||||
msgid "cannot transfer files when watching file descriptors"
|
||||
msgstr "não pode transferir arquivos ao assistir descritores de arquivo"
|
||||
|
||||
#: src/main/options.c:730
|
||||
#: src/main/options.c:741
|
||||
msgid "not available on systems without /proc/self/fdinfo"
|
||||
msgstr "não disponível em sistemas sem /proc/self/fdinfo"
|
||||
|
||||
@@ -384,45 +393,45 @@ msgstr "tentativa de bloqueio falhou"
|
||||
msgid "failed to open terminal"
|
||||
msgstr "erro abrindo o terminal"
|
||||
|
||||
#: src/pv/display.c:216
|
||||
#: src/pv/display.c:230
|
||||
msgid "yzafpnum kMGTPEZY"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:234
|
||||
#: src/pv/display.c:248
|
||||
msgid "yzafpnum KMGTPEZY"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:661 src/pv/transfer.c:970
|
||||
#: src/pv/display.c:675 src/pv/transfer.c:970
|
||||
msgid "buffer allocation failed"
|
||||
msgstr "erro alocando o buffer"
|
||||
|
||||
#: src/pv/display.c:790
|
||||
#: src/pv/display.c:804
|
||||
msgid "b"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:793 src/pv/transfer.c:602
|
||||
#: src/pv/display.c:807 src/pv/transfer.c:602
|
||||
msgid "B"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:837 src/pv/display.c:852 src/pv/display.c:1071
|
||||
#: src/pv/loop.c:418
|
||||
#: src/pv/display.c:851 src/pv/display.c:866 src/pv/display.c:1085
|
||||
#: src/pv/loop.c:494
|
||||
msgid "b/s"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:841 src/pv/display.c:856 src/pv/display.c:1075
|
||||
#: src/pv/display.c:855 src/pv/display.c:870 src/pv/display.c:1089
|
||||
msgid "/s"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:841 src/pv/display.c:856 src/pv/display.c:1075
|
||||
#: src/pv/loop.c:418
|
||||
#: src/pv/display.c:855 src/pv/display.c:870 src/pv/display.c:1089
|
||||
#: src/pv/loop.c:494
|
||||
msgid "B/s"
|
||||
msgstr "B/s"
|
||||
|
||||
#: src/pv/display.c:884 src/pv/display.c:888
|
||||
#: src/pv/display.c:898 src/pv/display.c:902
|
||||
msgid "ETA"
|
||||
msgstr "ETA"
|
||||
|
||||
#: src/pv/display.c:954
|
||||
#: src/pv/display.c:968
|
||||
msgid "FIN"
|
||||
msgstr ""
|
||||
|
||||
@@ -454,15 +463,15 @@ msgstr ""
|
||||
msgid "(stdin)"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/loop.c:417
|
||||
#: src/pv/loop.c:493
|
||||
msgid "rate min/avg/max/mdev"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/loop.c:429
|
||||
#: src/pv/loop.c:505
|
||||
msgid "rate not measured"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/loop.c:635 src/pv/loop.c:686 src/pv/loop.c:727 src/pv/watchpid.c:99
|
||||
#: src/pv/loop.c:711 src/pv/loop.c:762 src/pv/loop.c:803 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
|
||||
@@ -474,7 +483,7 @@ msgstr ""
|
||||
msgid "history structure allocation failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/state.c:470 src/pv/state.c:481
|
||||
#: src/pv/state.c:501 src/pv/state.c:512
|
||||
msgid "file list allocation failed"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ struct opts_s {
|
||||
/*@keep@*/ /*@null@*/ char *name; /* display name, if any */
|
||||
/*@keep@*/ /*@null@*/ char *format; /* output format, if any */
|
||||
/*@keep@*/ /*@null@*/ char *pidfile; /* PID file, if any */
|
||||
/*@keep@*/ /*@null@*/ char *store_and_forward_file; /* store and forward file, if any */
|
||||
/*@keep@*/ /*@null@*/ const char **argv; /* array of non-option arguments */
|
||||
size_t lastwritten; /* show N bytes last written */
|
||||
off_t rate_limit; /* rate limit, in bytes per second */
|
||||
|
||||
@@ -230,13 +230,13 @@ struct pvstate_s {
|
||||
/* Keep track of progress over last intervals to compute current average rate. */
|
||||
/*@null@*/ struct { /* state at previous intervals (circular buffer) */
|
||||
long double elapsed_sec; /* time since start of transfer */
|
||||
off_t total_written; /* amount transferred by that time */
|
||||
off_t transferred; /* amount transferred by that time */
|
||||
} *history;
|
||||
size_t history_len; /* total size of history array */
|
||||
size_t history_first; /* index of oldest entry */
|
||||
size_t history_last; /* index of newest entry */
|
||||
|
||||
off_t prev_total_written; /* total amount transferred when called last time */
|
||||
off_t prev_transferred; /* total amount transferred when called last time */
|
||||
|
||||
int percentage; /* transfer percentage completion */
|
||||
} calc;
|
||||
@@ -290,7 +290,10 @@ struct pvstate_s {
|
||||
ssize_t to_write; /* max to write this time around */
|
||||
ssize_t written; /* bytes sent to stdout this time */
|
||||
|
||||
off_t total_written; /* total bytes or lines transferred */
|
||||
size_t written_but_not_consumed; /* bytes in the output pipe, unread */
|
||||
|
||||
off_t total_written; /* total bytes or lines written */
|
||||
off_t transferred; /* amount transferred (written - unconsumed) */
|
||||
|
||||
/*
|
||||
* While reading from a file descriptor we keep track of how
|
||||
|
||||
@@ -27,6 +27,7 @@ extern "C" {
|
||||
* Exit status bitmask values.
|
||||
*/
|
||||
#define PV_ERROREXIT_REMOTE_OR_PID 1
|
||||
#define PV_ERROREXIT_SAF 1 /* store and forward error */
|
||||
#define PV_ERROREXIT_ACCESS 2
|
||||
#define PV_ERROREXIT_OUROBOROS 4
|
||||
#define PV_ERROREXIT_TRANSITION 8
|
||||
@@ -163,6 +164,11 @@ void pv_nanosleep(long long);
|
||||
*/
|
||||
extern /*@null@*/ /*@only@*/ pvstate_t pv_state_alloc(const char *);
|
||||
|
||||
/*
|
||||
* Clear the calculated parts of a state structure.
|
||||
*/
|
||||
extern void pv_state_reset(pvstate_t state);
|
||||
|
||||
/*
|
||||
* Set the formatting string, given a set of old-style formatting options.
|
||||
*/
|
||||
|
||||
@@ -396,6 +396,9 @@ void display_help(void)
|
||||
{ "-X", "--discard", NULL,
|
||||
N_("discard input instead of writing to output"),
|
||||
{ 0, 0, 0, 0} },
|
||||
{ "-U", "--store-and-forward", N_("FILE"),
|
||||
N_("write all input to FILE before writing to output"),
|
||||
{ 0, 0, 0, 0} },
|
||||
#ifdef SA_SIGINFO
|
||||
{ "-R", "--remote", N_("PID"),
|
||||
N_("update settings of process PID"),
|
||||
|
||||
+246
-93
@@ -25,6 +25,233 @@ int pv_remote_set(opts_t, pvstate_t);
|
||||
void pv_remote_init(void);
|
||||
void pv_remote_fini(void);
|
||||
|
||||
/*
|
||||
* Write a PID file, returning nonzero on error.
|
||||
*/
|
||||
static int pv__write_pidfile(opts_t opts)
|
||||
{
|
||||
char *pidfile_tmp_name;
|
||||
size_t pidfile_tmp_bufsize;
|
||||
int pidfile_tmp_fd;
|
||||
FILE *pidfile_tmp_fptr;
|
||||
mode_t prev_umask;
|
||||
|
||||
if (NULL == opts->pidfile)
|
||||
return 0;
|
||||
|
||||
pidfile_tmp_bufsize = 16 + strlen(opts->pidfile); /* flawfinder: ignore */
|
||||
/*
|
||||
* flawfinder rationale: pidfile was supplied as an argument
|
||||
* so we have to assume it is \0 terminated.
|
||||
*/
|
||||
pidfile_tmp_name = malloc(pidfile_tmp_bufsize);
|
||||
if (NULL == pidfile_tmp_name) {
|
||||
fprintf(stderr, "%s: %s\n", opts->program_name, strerror(errno));
|
||||
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);
|
||||
|
||||
/*@-type@ *//* splint doesn't like mode_t */
|
||||
prev_umask = umask(0000); /* flawfinder: ignore */
|
||||
(void) umask(prev_umask | 0133); /* flawfinder: ignore */
|
||||
|
||||
/*@-unrecog@ *//* splint doesn't know mkstemp() */
|
||||
pidfile_tmp_fd = mkstemp(pidfile_tmp_name); /* flawfinder: ignore */
|
||||
/*@+unrecog@ */
|
||||
if (pidfile_tmp_fd < 0) {
|
||||
fprintf(stderr, "%s: %s: %s\n", opts->program_name, pidfile_tmp_name, strerror(errno));
|
||||
(void) umask(prev_umask); /* flawfinder: ignore */
|
||||
free(pidfile_tmp_name);
|
||||
return PV_ERROREXIT_REMOTE_OR_PID;
|
||||
}
|
||||
|
||||
(void) umask(prev_umask); /* flawfinder: ignore */
|
||||
|
||||
/*
|
||||
* flawfinder rationale (umask, mkstemp) - flawfinder
|
||||
* recommends setting the most restrictive umask possible
|
||||
* when calling mkstemp(), so this is what we have done.
|
||||
*
|
||||
* We get the original umask and OR it with 0133 to make
|
||||
* sure new files will be at least chmod 644. Then we put
|
||||
* the umask back to what it was, after creating the
|
||||
* temporary file.
|
||||
*/
|
||||
|
||||
/*@+type@ */
|
||||
|
||||
pidfile_tmp_fptr = fdopen(pidfile_tmp_fd, "w");
|
||||
if (NULL == pidfile_tmp_fptr) {
|
||||
fprintf(stderr, "%s: %s: %s\n", opts->program_name, pidfile_tmp_name, strerror(errno));
|
||||
(void) close(pidfile_tmp_fd);
|
||||
(void) remove(pidfile_tmp_name);
|
||||
free(pidfile_tmp_name);
|
||||
return PV_ERROREXIT_REMOTE_OR_PID;
|
||||
}
|
||||
|
||||
fprintf(pidfile_tmp_fptr, "%d\n", getpid());
|
||||
if (0 != fclose(pidfile_tmp_fptr)) {
|
||||
fprintf(stderr, "%s: %s: %s\n", opts->program_name, opts->pidfile, strerror(errno));
|
||||
}
|
||||
|
||||
if (rename(pidfile_tmp_name, opts->pidfile) < 0) {
|
||||
fprintf(stderr, "%s: %s: %s\n", opts->program_name, opts->pidfile, strerror(errno));
|
||||
(void) remove(pidfile_tmp_name);
|
||||
}
|
||||
|
||||
free(pidfile_tmp_name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set the output file, if applicable. Returns nonzero on error.
|
||||
*/
|
||||
static int pv__set_output(pvstate_t state, opts_t opts, /*@null@ */ const char *output_file)
|
||||
{
|
||||
int output_fd;
|
||||
|
||||
if ((NULL == state) || (NULL == opts))
|
||||
return 0;
|
||||
|
||||
if (NULL == output_file || 0 == strcmp(output_file, "-")) {
|
||||
pv_state_output_set(state, STDOUT_FILENO, "(stdout)");
|
||||
return 0;
|
||||
}
|
||||
|
||||
output_fd = open(output_file, O_WRONLY | O_CREAT | O_TRUNC, 0600); /* flawfinder: ignore */
|
||||
/*
|
||||
* flawfinder rationale: the output filename has been
|
||||
* explicitly provided, and in many cases the operator will
|
||||
* want to write to device files and other special
|
||||
* destinations, so there is no sense-checking we can do to
|
||||
* make this safer.
|
||||
*/
|
||||
if (output_fd < 0) {
|
||||
fprintf(stderr, "%s: %s: %s\n", opts->program_name, output_file, strerror(errno));
|
||||
return PV_ERROREXIT_ACCESS;
|
||||
}
|
||||
|
||||
pv_state_output_set(state, output_fd, output_file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Run in store-and-forward mode: run the main loop once with the output
|
||||
* forced to the store-and-forward file (taking care of creation and removal
|
||||
* of a temporary file if "-" was specified); then run the main loop again
|
||||
* with the input file list forced to be just the store-and-forward file.
|
||||
* Returns nonzero on error.
|
||||
*/
|
||||
static int pv__store_and_forward(pvstate_t state, opts_t opts, bool can_have_eta)
|
||||
{
|
||||
char tmp_filename[4096]; /* flawfinder: ignore */
|
||||
bool use_temporary_file;
|
||||
char *real_store_and_forward_file;
|
||||
int retcode;
|
||||
|
||||
/* flawfinder: zeroed with memset and bounded by pv_snprintf. */
|
||||
|
||||
if ((NULL == state) || (NULL == opts) || (NULL == opts->store_and_forward_file))
|
||||
return 0;
|
||||
|
||||
memset(tmp_filename, 0, sizeof(tmp_filename));
|
||||
|
||||
use_temporary_file = false;
|
||||
if (0 == strcmp(opts->store_and_forward_file, "-"))
|
||||
use_temporary_file = true;
|
||||
|
||||
/*
|
||||
* Create a temporary file if the specified file was "-".
|
||||
*/
|
||||
if (use_temporary_file) {
|
||||
char *tmpdir;
|
||||
int tmp_fd;
|
||||
|
||||
tmpdir = (char *) getenv("TMPDIR"); /* flawfinder: ignore */
|
||||
if ((NULL == tmpdir) || ('\0' == tmpdir[0]))
|
||||
tmpdir = (char *) getenv("TMP"); /* flawfinder: ignore */
|
||||
if ((NULL == tmpdir) || ('\0' == tmpdir[0]))
|
||||
tmpdir = "/tmp";
|
||||
|
||||
/*
|
||||
* flawfinder rationale: null and zero-size values of $TMPDIR and
|
||||
* $TMP are rejected, and the destination buffer is bounded.
|
||||
*/
|
||||
|
||||
(void) pv_snprintf(tmp_filename, sizeof(tmp_filename), "%s/pv.XXXXXX", tmpdir);
|
||||
/*@-unrecog@ *//* splint doesn't know mkstemp() */
|
||||
tmp_fd = mkstemp(tmp_filename); /* flawfinder: ignore */
|
||||
/*@+unrecog@ */
|
||||
if (tmp_fd < 0) {
|
||||
fprintf(stderr, "%s: %s: %s\n", opts->program_name, tmp_filename, strerror(errno));
|
||||
return PV_ERROREXIT_SAF;
|
||||
}
|
||||
(void) close(tmp_fd);
|
||||
}
|
||||
|
||||
/*
|
||||
* Real store-and-forward file: either the one we were given, or the
|
||||
* temporary file we created if we were given "-".
|
||||
*/
|
||||
real_store_and_forward_file = use_temporary_file ? tmp_filename : opts->store_and_forward_file;
|
||||
|
||||
/*
|
||||
* First, set the output file to the store-and-forward file.
|
||||
*/
|
||||
debug("%s: %s", "setting output to store-and-forward file", real_store_and_forward_file);
|
||||
retcode = pv__set_output(state, opts, real_store_and_forward_file);
|
||||
if (0 != retcode)
|
||||
goto end_store_and_forward;
|
||||
|
||||
/* Reset the formatting to set the displayed name to "(input)". */
|
||||
/*@-mustfreefresh@ */
|
||||
pv_state_set_format(state, opts->progress, opts->timer, can_have_eta ? opts->eta : false,
|
||||
can_have_eta ? opts->fineta : false, opts->rate, opts->average_rate,
|
||||
opts->bytes, opts->bufpercent, opts->lastwritten, _("(input)"));
|
||||
/*@+mustfreefresh@ *//* see below about gettext _() calls. */
|
||||
|
||||
/* Run the main loop as normal. */
|
||||
debug("%s", "running store-and-forward receiver");
|
||||
retcode = pv_main_loop(state);
|
||||
if (0 != retcode)
|
||||
goto end_store_and_forward;
|
||||
|
||||
/* Set the output file back to what it originally was. */
|
||||
debug("%s: %s", "setting output to original value", NULL == opts->output ? "(null)" : opts->output);
|
||||
retcode = pv__set_output(state, opts, opts->output);
|
||||
if (0 != retcode)
|
||||
goto end_store_and_forward;
|
||||
|
||||
/* Replace the list of input files with the store-and-forward file. */
|
||||
debug("%s", "resetting input file list");
|
||||
pv_state_inputfiles(state, 1, (const char **) &real_store_and_forward_file);
|
||||
|
||||
/* Recalculate the input size. */
|
||||
pv_state_size_set(state, pv_calc_total_size(state));
|
||||
|
||||
/* Reset the format, since we might have been asked to show ETA. */
|
||||
pv_state_set_format(state, opts->progress, opts->timer, opts->eta,
|
||||
opts->fineta, opts->rate, opts->average_rate,
|
||||
opts->bytes, opts->bufpercent, opts->lastwritten, opts->name);
|
||||
|
||||
/* Reset calculated values in the state. */
|
||||
pv_state_reset(state);
|
||||
|
||||
/* Run the main loop again. */
|
||||
debug("%s", "running store-and-forward transmitter");
|
||||
retcode = pv_main_loop(state);
|
||||
|
||||
end_store_and_forward:
|
||||
if (use_temporary_file)
|
||||
(void) remove(tmp_filename);
|
||||
|
||||
return retcode;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Process command-line arguments and set option flags, then call functions
|
||||
@@ -35,6 +262,7 @@ int main(int argc, char **argv)
|
||||
/*@only@ */ opts_t opts = NULL;
|
||||
/*@only@ */ pvstate_t state = NULL;
|
||||
int retcode = 0;
|
||||
bool can_have_eta = true;
|
||||
|
||||
#ifdef ENABLE_NLS
|
||||
/* Initialise language translation. */
|
||||
@@ -96,80 +324,13 @@ int main(int argc, char **argv)
|
||||
* Write a PID file if -P was specified.
|
||||
*/
|
||||
if (opts->pidfile != NULL) {
|
||||
char *pidfile_tmp_name;
|
||||
size_t pidfile_tmp_bufsize;
|
||||
int pidfile_tmp_fd;
|
||||
FILE *pidfile_tmp_fptr;
|
||||
mode_t prev_umask;
|
||||
|
||||
pidfile_tmp_bufsize = 16 + strlen(opts->pidfile); /* flawfinder: ignore */
|
||||
/*
|
||||
* flawfinder rationale: pidfile was supplied as an argument
|
||||
* so we have to assume it is \0 terminated.
|
||||
*/
|
||||
pidfile_tmp_name = malloc(pidfile_tmp_bufsize);
|
||||
if (NULL == pidfile_tmp_name) {
|
||||
fprintf(stderr, "%s: %s\n", opts->program_name, strerror(errno));
|
||||
int pidfile_rc;
|
||||
pidfile_rc = pv__write_pidfile(opts);
|
||||
if (0 != pidfile_rc) {
|
||||
pv_state_free(state);
|
||||
opts_free(opts);
|
||||
return PV_ERROREXIT_REMOTE_OR_PID;
|
||||
return pidfile_rc;
|
||||
}
|
||||
memset(pidfile_tmp_name, 0, pidfile_tmp_bufsize);
|
||||
(void) pv_snprintf(pidfile_tmp_name, pidfile_tmp_bufsize, "%s.XXXXXX", opts->pidfile);
|
||||
|
||||
/*@-type@ *//* splint doesn't like mode_t */
|
||||
prev_umask = umask(0000); /* flawfinder: ignore */
|
||||
(void) umask(prev_umask | 0133); /* flawfinder: ignore */
|
||||
|
||||
/*@-unrecog@ *//* splint doesn't know mkstemp() */
|
||||
pidfile_tmp_fd = mkstemp(pidfile_tmp_name); /* flawfinder: ignore */
|
||||
/*@+unrecog@ */
|
||||
if (pidfile_tmp_fd < 0) {
|
||||
fprintf(stderr, "%s: %s: %s\n", opts->program_name, pidfile_tmp_name, strerror(errno));
|
||||
(void) umask(prev_umask); /* flawfinder: ignore */
|
||||
free(pidfile_tmp_name);
|
||||
pv_state_free(state);
|
||||
opts_free(opts);
|
||||
return PV_ERROREXIT_REMOTE_OR_PID;
|
||||
}
|
||||
|
||||
(void) umask(prev_umask); /* flawfinder: ignore */
|
||||
|
||||
/*
|
||||
* flawfinder rationale (umask, mkstemp) - flawfinder
|
||||
* recommends setting the most restrictive umask possible
|
||||
* when calling mkstemp(), so this is what we have done.
|
||||
*
|
||||
* We get the original umask and OR it with 0133 to make
|
||||
* sure new files will be at least chmod 644. Then we put
|
||||
* the umask back to what it was, after creating the
|
||||
* temporary file.
|
||||
*/
|
||||
|
||||
/*@+type@ */
|
||||
|
||||
pidfile_tmp_fptr = fdopen(pidfile_tmp_fd, "w");
|
||||
if (NULL == pidfile_tmp_fptr) {
|
||||
fprintf(stderr, "%s: %s: %s\n", opts->program_name, pidfile_tmp_name, strerror(errno));
|
||||
(void) close(pidfile_tmp_fd);
|
||||
(void) remove(pidfile_tmp_name);
|
||||
free(pidfile_tmp_name);
|
||||
pv_state_free(state);
|
||||
opts_free(opts);
|
||||
return PV_ERROREXIT_REMOTE_OR_PID;
|
||||
}
|
||||
|
||||
fprintf(pidfile_tmp_fptr, "%d\n", getpid());
|
||||
if (0 != fclose(pidfile_tmp_fptr)) {
|
||||
fprintf(stderr, "%s: %s: %s\n", opts->program_name, opts->pidfile, strerror(errno));
|
||||
}
|
||||
|
||||
if (rename(pidfile_tmp_name, opts->pidfile) < 0) {
|
||||
fprintf(stderr, "%s: %s: %s\n", opts->program_name, opts->pidfile, strerror(errno));
|
||||
(void) remove(pidfile_tmp_name);
|
||||
}
|
||||
|
||||
free(pidfile_tmp_name);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -246,24 +407,11 @@ int main(int argc, char **argv)
|
||||
* 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);
|
||||
retcode = pv__set_output(state, opts, opts->output);
|
||||
if (0 != retcode) {
|
||||
pv_state_free(state);
|
||||
opts_free(opts);
|
||||
return retcode;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -290,7 +438,7 @@ int main(int argc, char **argv)
|
||||
* If the size is unknown, we cannot have an ETA.
|
||||
*/
|
||||
if (opts->size < 1) {
|
||||
opts->eta = false;
|
||||
can_have_eta = false;
|
||||
debug("%s", "size unknown - ETA disabled");
|
||||
}
|
||||
}
|
||||
@@ -330,19 +478,24 @@ int main(int argc, char **argv)
|
||||
pv_state_watch_fd_set(state, opts->watch_fd);
|
||||
pv_state_average_rate_window_set(state, opts->average_rate_window);
|
||||
|
||||
pv_state_set_format(state, opts->progress, opts->timer, opts->eta,
|
||||
opts->fineta, opts->rate, opts->average_rate,
|
||||
pv_state_set_format(state, opts->progress, opts->timer, can_have_eta ? opts->eta : false,
|
||||
can_have_eta ? opts->fineta : false, opts->rate, opts->average_rate,
|
||||
opts->bytes, opts->bufpercent, opts->lastwritten, opts->name);
|
||||
|
||||
/* Initialise the signal handling. */
|
||||
pv_sig_init(state);
|
||||
|
||||
/* Run the appropriate main loop. */
|
||||
if (0 == opts->watch_pid) {
|
||||
if (0 == opts->watch_pid && NULL == opts->store_and_forward_file) {
|
||||
/* Normal "transfer data" mode. */
|
||||
pv_remote_init();
|
||||
retcode = pv_main_loop(state);
|
||||
pv_remote_fini();
|
||||
} else if (0 == opts->watch_pid && NULL != opts->store_and_forward_file) {
|
||||
/* Store-and-forward transfer mode. */
|
||||
pv_remote_init();
|
||||
retcode = pv__store_and_forward(state, opts, can_have_eta);
|
||||
pv_remote_fini();
|
||||
} else if (0 != opts->watch_pid && -1 == opts->watch_fd) {
|
||||
/* "Watch all file descriptors of another process" mode. */
|
||||
retcode = pv_watchpid_loop(state);
|
||||
|
||||
+12
-1
@@ -55,6 +55,8 @@ void opts_free( /*@only@ */ opts_t opts)
|
||||
free(opts->pidfile);
|
||||
if (NULL != opts->output)
|
||||
free(opts->output);
|
||||
if (NULL != opts->store_and_forward_file)
|
||||
free(opts->store_and_forward_file);
|
||||
if (NULL != opts->argv)
|
||||
free(opts->argv);
|
||||
/*@+keeptrans@ */
|
||||
@@ -301,6 +303,7 @@ opts_t opts_parse(unsigned int argc, char **argv)
|
||||
{ "sync", 0, NULL, (int) 'Y' },
|
||||
{ "direct-io", 0, NULL, (int) 'K' },
|
||||
{ "discard", 0, NULL, (int) 'X' },
|
||||
{ "store-and-forward", 1, NULL, (int) 'U' },
|
||||
{ "remote", 1, NULL, (int) 'R' },
|
||||
{ "pidfile", 1, NULL, (int) 'P' },
|
||||
{ "watchfd", 1, NULL, (int) 'd' },
|
||||
@@ -314,7 +317,7 @@ opts_t opts_parse(unsigned int argc, char **argv)
|
||||
/*@+nullassign@ */
|
||||
int option_index = 0;
|
||||
#endif /* HAVE_GETOPT_LONG */
|
||||
char *short_options = "hVpteIrab8kTA:fvnqcWD:s:gl0i:w:H:N:F:L:B:CEZ:SYKXR:P:d:m:o:"
|
||||
char *short_options = "hVpteIrab8kTA:fvnqcWD:s:gl0i:w:H:N:F:L:B:CEZ:SYKXU:R:P:d:m:o:"
|
||||
#ifdef ENABLE_DEBUGGING
|
||||
"!:"
|
||||
#endif
|
||||
@@ -605,6 +608,14 @@ opts_t opts_parse(unsigned int argc, char **argv)
|
||||
opts->discard_input = true;
|
||||
opts->no_splice = true;
|
||||
break;
|
||||
case 'U':
|
||||
opts->store_and_forward_file = pv_strdup(optarg);
|
||||
if (NULL == opts->store_and_forward_file) {
|
||||
fprintf(stderr, "%s: -U: %s\n", opts->program_name, strerror(errno));
|
||||
opts_free(opts);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case 'R':
|
||||
opts->remote = pv_getnum_count(optarg, false);
|
||||
break;
|
||||
|
||||
+7
-7
@@ -51,12 +51,12 @@ static void pv__update_average_rate_history(pvstate_t state, long double rate)
|
||||
}
|
||||
|
||||
state->calc.history[last].elapsed_sec = state->transfer.elapsed_seconds;
|
||||
state->calc.history[last].total_written = state->transfer.total_written;
|
||||
state->calc.history[last].transferred = state->transfer.transferred;
|
||||
|
||||
if (first == last) {
|
||||
state->calc.current_avg_rate = rate;
|
||||
} else {
|
||||
off_t bytes = (state->calc.history[last].total_written - state->calc.history[first].total_written);
|
||||
off_t bytes = (state->calc.history[last].transferred - state->calc.history[first].transferred);
|
||||
long double sec = (state->calc.history[last].elapsed_sec - state->calc.history[first].elapsed_sec);
|
||||
state->calc.current_avg_rate = (long double) bytes / sec;
|
||||
}
|
||||
@@ -85,9 +85,9 @@ void pv_calculate_transfer_rate(pvstate_t state, bool final)
|
||||
return;
|
||||
|
||||
bytes_since_last = 0;
|
||||
if (state->transfer.total_written >= 0) {
|
||||
bytes_since_last = state->transfer.total_written - state->calc.prev_total_written;
|
||||
state->calc.prev_total_written = state->transfer.total_written;
|
||||
if (state->transfer.transferred >= 0) {
|
||||
bytes_since_last = state->transfer.transferred - state->calc.prev_transferred;
|
||||
state->calc.prev_transferred = state->transfer.transferred;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -138,7 +138,7 @@ void pv_calculate_transfer_rate(pvstate_t state, bool final)
|
||||
if (state->transfer.elapsed_seconds < 0.000001)
|
||||
state->transfer.elapsed_seconds = 0.000001;
|
||||
average_rate =
|
||||
(((long double) state->transfer.total_written) -
|
||||
(((long double) (state->transfer.transferred)) -
|
||||
((long double) state->display.initial_offset)) / (long double) (state->transfer.elapsed_seconds);
|
||||
transfer_rate = average_rate;
|
||||
}
|
||||
@@ -160,7 +160,7 @@ void pv_calculate_transfer_rate(pvstate_t state, bool final)
|
||||
if (state->calc.percentage > 199)
|
||||
state->calc.percentage = 0;
|
||||
} else {
|
||||
state->calc.percentage = pv_percentage(state->transfer.total_written, state->control.size);
|
||||
state->calc.percentage = pv_percentage(state->transfer.transferred, state->control.size);
|
||||
}
|
||||
|
||||
/* Ensure the percentage is never negative or huge. */
|
||||
|
||||
+23
-9
@@ -119,14 +119,28 @@ void pv_write_retry(int fd, const char *buf, size_t count)
|
||||
|
||||
|
||||
/*
|
||||
* Write the given buffer to the terminal with pv_write_retry(), unless
|
||||
* Write the given buffer to the terminal, like pv_write_retry(), unless
|
||||
* stderr is suspended.
|
||||
*/
|
||||
void pv_tty_write(pvstate_t state, const char *buf, size_t count)
|
||||
{
|
||||
if (1 == state->flag.suspend_stderr)
|
||||
return;
|
||||
pv_write_retry(STDERR_FILENO, buf, count);
|
||||
while (0 == state->flag.suspend_stderr && count > 0) {
|
||||
ssize_t nwritten;
|
||||
|
||||
nwritten = write(STDERR_FILENO, buf, count);
|
||||
|
||||
if (nwritten < 0) {
|
||||
if ((EINTR == errno) || (EAGAIN == errno)) {
|
||||
continue;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (nwritten < 1)
|
||||
return;
|
||||
|
||||
count -= nwritten;
|
||||
buf += nwritten;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -706,7 +720,7 @@ bool pv_format(pvstate_t state, bool final)
|
||||
if (state->display.component[PV_COMPONENT_BYTES].required) {
|
||||
(void) pv_snprintf(msg_bytes, sizeof(msg_bytes),
|
||||
"%s%lld", first_item ? "" : " ",
|
||||
(long long) ((state->control.bits ? 8 : 1) * state->transfer.total_written));
|
||||
(long long) ((state->control.bits ? 8 : 1) * state->transfer.transferred));
|
||||
first_item = false;
|
||||
show_percentage = false;
|
||||
}
|
||||
@@ -787,10 +801,10 @@ bool pv_format(pvstate_t state, bool final)
|
||||
/*@-mustfreefresh @ */
|
||||
if (state->control.bits && !state->control.linemode) {
|
||||
pv__sizestr(component_content, component_buf_size, "%s",
|
||||
(long double) (state->transfer.total_written * 8), "", _("b"), count_type);
|
||||
(long double) (state->transfer.transferred * 8), "", _("b"), count_type);
|
||||
} else {
|
||||
pv__sizestr(component_content, component_buf_size, "%s",
|
||||
(long double) (state->transfer.total_written), "", _("B"), count_type);
|
||||
(long double) (state->transfer.transferred), "", _("B"), count_type);
|
||||
}
|
||||
/*@+mustfreefresh @ */
|
||||
/* splint: we trust gettext() not to really leak memory. */
|
||||
@@ -862,7 +876,7 @@ bool pv_format(pvstate_t state, bool final)
|
||||
case PV_COMPONENT_ETA:
|
||||
/* Estimated time remaining until completion - if size is known. */
|
||||
eta =
|
||||
pv__seconds_remaining((state->transfer.total_written - state->display.initial_offset),
|
||||
pv__seconds_remaining((state->transfer.transferred - state->display.initial_offset),
|
||||
state->control.size - state->display.initial_offset,
|
||||
state->calc.current_avg_rate);
|
||||
|
||||
@@ -917,7 +931,7 @@ bool pv_format(pvstate_t state, bool final)
|
||||
*/
|
||||
|
||||
eta =
|
||||
pv__seconds_remaining(state->transfer.total_written - state->display.initial_offset,
|
||||
pv__seconds_remaining(state->transfer.transferred - state->display.initial_offset,
|
||||
state->control.size - state->display.initial_offset,
|
||||
state->calc.current_avg_rate);
|
||||
|
||||
|
||||
+73
-4
@@ -68,6 +68,7 @@ int pv_main_loop(pvstate_t state)
|
||||
struct timespec init_time, next_remotecheck, transfer_elapsed;
|
||||
int input_fd, output_fd;
|
||||
unsigned int file_idx;
|
||||
bool output_is_pipe;
|
||||
|
||||
/*
|
||||
* "written" is ALWAYS bytes written by the last transfer.
|
||||
@@ -88,6 +89,35 @@ int pv_main_loop(pvstate_t state)
|
||||
if (output_fd < 0)
|
||||
output_fd = STDOUT_FILENO;
|
||||
|
||||
/* Determine whether the output is a pipe. */
|
||||
output_is_pipe = false;
|
||||
{
|
||||
struct stat sb;
|
||||
memset(&sb, 0, sizeof(sb));
|
||||
if (0 == fstat(output_fd, &sb)) {
|
||||
/*@-type@*/
|
||||
if ((sb.st_mode & S_IFMT) == S_IFIFO) {
|
||||
output_is_pipe = true;
|
||||
debug("%s", "output is a pipe");
|
||||
}
|
||||
/*@+type@*/ /* splint says st_mode is __mode_t, not mode_t */
|
||||
} else {
|
||||
debug("%s(%d): %s", "fstat", output_fd, strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that we could reduce the size of the output pipe buffer like
|
||||
* this, to avoid the case where we write a load of data and it just
|
||||
* goes into the buffer so we think we're done, but the consumer
|
||||
* takes ages to process it:
|
||||
*
|
||||
* fcntl(output_fd, F_SETPIPE_SZ, 4096);
|
||||
*
|
||||
* If we can peek at how much has been consumed by the other end, we
|
||||
* don't need to.
|
||||
*/
|
||||
|
||||
pv_crs_init(state);
|
||||
|
||||
eof_in = false;
|
||||
@@ -95,6 +125,7 @@ int pv_main_loop(pvstate_t state)
|
||||
state->transfer.total_written = 0;
|
||||
lineswritten = 0;
|
||||
state->display.initial_offset = 0;
|
||||
state->transfer.written_but_not_consumed = 0;
|
||||
|
||||
memset(&cur_time, 0, sizeof(cur_time));
|
||||
memset(&start_time, 0, sizeof(start_time));
|
||||
@@ -147,8 +178,7 @@ int pv_main_loop(pvstate_t state)
|
||||
/*
|
||||
* Set or clear O_DIRECT on the output.
|
||||
*/
|
||||
if (0 !=
|
||||
fcntl(output_fd, F_SETFL, (state->control.direct_io ? O_DIRECT : 0) | fcntl(output_fd, F_GETFL))) {
|
||||
if (0 != fcntl(output_fd, F_SETFL, (state->control.direct_io ? O_DIRECT : 0) | fcntl(output_fd, F_GETFL))) {
|
||||
debug("%s: %s", "fcntl", strerror(errno));
|
||||
}
|
||||
state->control.direct_io_changed = false;
|
||||
@@ -176,6 +206,11 @@ int pv_main_loop(pvstate_t state)
|
||||
if (0 == state->control.target_buffer_size)
|
||||
state->control.target_buffer_size = BUFFER_SIZE;
|
||||
|
||||
/*
|
||||
* Repeat until eof_in is true, eof_out is true, and final_update is
|
||||
* true.
|
||||
*/
|
||||
|
||||
while ((!(eof_in && eof_out)) || (!final_update)) {
|
||||
|
||||
cansend = 0;
|
||||
@@ -249,6 +284,36 @@ int pv_main_loop(pvstate_t state)
|
||||
target -= written;
|
||||
}
|
||||
|
||||
#ifdef FIONREAD
|
||||
/*
|
||||
* If writing to a pipe, look at how much is sitting in the
|
||||
* pipe buffer waiting for the receiver to read.
|
||||
*/
|
||||
if (output_is_pipe) {
|
||||
int nbytes;
|
||||
nbytes = 0;
|
||||
if (0 == ioctl(output_fd, FIONREAD, &nbytes)) {
|
||||
if (nbytes >= 0) {
|
||||
if (((size_t) nbytes) != state->transfer.written_but_not_consumed)
|
||||
debug("%s: %d", "written_but_not_consumed is now", nbytes);
|
||||
state->transfer.written_but_not_consumed = (size_t) nbytes;
|
||||
} else {
|
||||
debug("%s: %d", "FIONREAD gave a negative byte count", nbytes);
|
||||
state->transfer.written_but_not_consumed = 0;
|
||||
}
|
||||
} else {
|
||||
debug("%s(%d,%s): %s", "ioctl", output_fd, "FIONREAD", strerror(errno));
|
||||
state->transfer.written_but_not_consumed = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
state->transfer.transferred = state->transfer.total_written;
|
||||
/* TODO: work out what to do in line mode. */
|
||||
if (output_is_pipe && !state->control.linemode) {
|
||||
state->transfer.transferred -= state->transfer.written_but_not_consumed;
|
||||
}
|
||||
|
||||
/*
|
||||
* EOF, and files remain - advance to the next file.
|
||||
*/
|
||||
@@ -268,8 +333,12 @@ int pv_main_loop(pvstate_t state)
|
||||
/* Now check the current time. */
|
||||
pv_elapsedtime_read(&cur_time);
|
||||
|
||||
/* If full EOF, final update, and force a display updaate. */
|
||||
if (eof_in && eof_out) {
|
||||
/*
|
||||
* If we've read everything and written everything, and the
|
||||
* output pipe buffer is empty, then set the final update
|
||||
* flag, and force a display update.
|
||||
*/
|
||||
if (eof_in && eof_out && 0 == state->transfer.written_but_not_consumed) {
|
||||
final_update = true;
|
||||
if ((state->display.display_visible)
|
||||
|| (state->control.delay_start < 0.001)) {
|
||||
|
||||
+53
-22
@@ -46,6 +46,58 @@ static void pv_alloc_history(pvstate_t state)
|
||||
state->calc.history[0].elapsed_sec = 0.0; /* to be safe, memset() not recommended for doubles */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Clear the calculated parts of a state structure.
|
||||
*/
|
||||
void pv_state_reset(pvstate_t state)
|
||||
{
|
||||
if (NULL == state)
|
||||
return;
|
||||
|
||||
state->flag.reparse_display = 1;
|
||||
state->status.current_input_file = -1;
|
||||
|
||||
state->display.initial_offset = 0;
|
||||
state->display.display_visible = false;
|
||||
|
||||
/*
|
||||
* Explicitly set important floating point values to 0, as memset()
|
||||
* is not recommended for this.
|
||||
*/
|
||||
state->calc.transfer_rate = 0.0;
|
||||
state->calc.average_rate = 0.0;
|
||||
state->calc.prev_elapsed_sec = 0.0;
|
||||
state->calc.prev_rate = 0.0;
|
||||
state->calc.prev_trans = 0.0;
|
||||
state->calc.current_avg_rate = 0.0;
|
||||
state->calc.rate_min = 0.0;
|
||||
state->calc.rate_max = 0.0;
|
||||
state->calc.rate_sum = 0.0;
|
||||
state->calc.ratesquared_sum = 0.0;
|
||||
state->calc.measurements_taken = 0;
|
||||
state->calc.prev_transferred = 0;
|
||||
state->calc.percentage = 0;
|
||||
state->calc.history_first = state->calc.history_last = 0;
|
||||
if (NULL != state->calc.history) {
|
||||
state->calc.history[0].elapsed_sec = 0.0;
|
||||
}
|
||||
|
||||
state->transfer.elapsed_seconds = 0.0;
|
||||
state->transfer.read_position = 0;
|
||||
state->transfer.write_position = 0;
|
||||
state->transfer.to_write = 0;
|
||||
state->transfer.written = 0;
|
||||
state->transfer.total_written = 0;
|
||||
state->transfer.written_but_not_consumed = 0;
|
||||
state->transfer.read_errors_in_a_row = 0;
|
||||
state->transfer.last_read_skip_fd = 0;
|
||||
#ifdef HAVE_SPLICE
|
||||
state->transfer.splice_failed_fd = -1;
|
||||
#endif /* HAVE_SPLICE */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Create a new state structure, and return it, or 0 (NULL) on error.
|
||||
*/
|
||||
@@ -78,28 +130,7 @@ pvstate_t pv_state_alloc(const char *program_name)
|
||||
#endif /* HAVE_IPC */
|
||||
state->cursor.lock_fd = -1;
|
||||
|
||||
state->flag.reparse_display = 1;
|
||||
state->status.current_input_file = -1;
|
||||
#ifdef HAVE_SPLICE
|
||||
state->transfer.splice_failed_fd = -1;
|
||||
#endif /* HAVE_SPLICE */
|
||||
state->display.display_visible = false;
|
||||
|
||||
/*
|
||||
* Explicitly set important floating point values to 0, as memset()
|
||||
* is not recommended for this.
|
||||
*/
|
||||
state->calc.transfer_rate = 0.0;
|
||||
state->calc.average_rate = 0.0;
|
||||
state->calc.prev_elapsed_sec = 0.0;
|
||||
state->calc.prev_rate = 0.0;
|
||||
state->calc.prev_trans = 0.0;
|
||||
state->calc.current_avg_rate = 0.0;
|
||||
state->calc.rate_min = 0.0;
|
||||
state->calc.rate_max = 0.0;
|
||||
state->calc.rate_sum = 0.0;
|
||||
state->calc.ratesquared_sum = 0.0;
|
||||
state->transfer.elapsed_seconds = 0.0;
|
||||
pv_state_reset(state);
|
||||
|
||||
/*
|
||||
* Get the current working directory, if possible, as a base for
|
||||
|
||||
Reference in New Issue
Block a user