From 9bd5a518eaf688f91bb2c28b403fd9d84cfa3adc Mon Sep 17 00:00:00 2001 From: Andrew Wood Date: Fri, 4 Oct 2024 15:12:22 +0100 Subject: [PATCH] New option "--stats", to show a line of statistics about the transfer once it has ended (issue #49). --- configure.ac | 4 ++ docs/ACKNOWLEDGEMENTS.md | 1 + docs/NEWS.md | 1 + docs/pv.1 | 8 ++- docs/pv.1.md | 12 +++- po/de.po | 140 +++++++++++++++++++++----------------- po/fr.po | 140 +++++++++++++++++++++----------------- po/pl.po | 140 +++++++++++++++++++++----------------- po/pt.po | 140 +++++++++++++++++++++----------------- src/include/config.h.in | 6 ++ src/include/options.h | 1 + src/include/pv-internal.h | 7 ++ src/include/pv.h | 1 + src/main/help.c | 3 + src/main/main.c | 1 + src/main/options.c | 6 +- src/pv/display.c | 18 +++++ src/pv/loop.c | 87 ++++++++++++++++++++++- src/pv/state.c | 21 ++++++ 19 files changed, 473 insertions(+), 264 deletions(-) diff --git a/configure.ac b/configure.ac index ee5b54e..2d52a83 100644 --- a/configure.ac +++ b/configure.ac @@ -40,6 +40,10 @@ AC_CHECK_HEADERS([libintl.h locale.h]) AC_CHECK_HEADERS([sys/sysmacros.h]) AC_CHECK_MEMBERS([struct stat.st_blksize]) +AC_SEARCH_LIBS([sqrtl],[m]) +AC_CHECK_HEADERS([math.h]) +AC_CHECK_FUNCS([sqrtl]) + dnl Libraries that may contain key functions. AC_SEARCH_LIBS([clock_gettime],[rt]) diff --git a/docs/ACKNOWLEDGEMENTS.md b/docs/ACKNOWLEDGEMENTS.md index b3a0c9f..781d458 100644 --- a/docs/ACKNOWLEDGEMENTS.md +++ b/docs/ACKNOWLEDGEMENTS.md @@ -97,5 +97,6 @@ is acknowledged and greatly appreciated: * [alexanderperlis](https://codeberg.org/alexanderperlis) - provided initial support for block devices with "`--size @FILE`" ([#94](https://codeberg.org/a-j-wood/pv/pulls/94)) * [jettero](https://codeberg.org/jettero) - reported double-free coredump when using "`--watchfd`" after 1.8.10 ([#96](https://codeberg.org/a-j-wood/pv/issues/96)) * Hartmut Goebel - provided a full set of new German translations ([#98](https://codeberg.org/a-j-wood/pv/pulls/98)) + * Venky.N.Iyer - suggested "`--stats`" ([#49](https://codeberg.org/a-j-wood/pv/issues/49)) --- diff --git a/docs/NEWS.md b/docs/NEWS.md index ccb4ce4..51480de 100644 --- a/docs/NEWS.md +++ b/docs/NEWS.md @@ -1,5 +1,6 @@ ### UNRELEASED + * feature: new "`--stats`" option to show transfer stats at the end, like "`ping`" ([#49](https://codeberg.org/a-j-wood/pv/issues/49)) * i18n: complete set of German translations supplied by Hartmut Goebel ([#98](https://codeberg.org/a-j-wood/pv/pulls/98)) * fix: resume stopped pipelines when running in the background (part of [#56](https://codeberg.org/a-j-wood/pv/issues/56)) * fix: write UTC timestamps in debugging mode to avoid lockups in signal handlers diff --git a/docs/pv.1 b/docs/pv.1 index 6b41f3c..a84f905 100644 --- a/docs/pv.1 +++ b/docs/pv.1 @@ -1,4 +1,4 @@ -.TH PV 1 "September 2024" Linux "User Manuals" +.TH PV 1 "October 2024" Linux "User Manuals" .SH NAME pv \- monitor the progress of data through a pipe .SH SYNOPSIS @@ -195,6 +195,12 @@ to determine the output format. See the .B FORMATTING section below. .TP +.B \-v, \-\-stats +At the end of the transfer, write an additional line showing the transfer +rate minimum, maximum, mean, and standard deviation. The values are always +in bytes per second (or bits, with +.BR \-8 ). +.TP .B \-n, \-\-numeric Numeric output. Instead of giving a visual indication of progress, .B pv diff --git a/docs/pv.1.md b/docs/pv.1.md index 02ae8da..4d87e34 100644 --- a/docs/pv.1.md +++ b/docs/pv.1.md @@ -34,9 +34,9 @@ the expected size to **pv**: A more complicated example using numeric output to feed into the **dialog**(1) program for a full-screen progress display: -> **(tar cf - . \\** \ -> **\| pv -n -s \$(du -sb . \| awk \'{print \$1}\') \\** \ -> **\| gzip -9 \> out.tgz) 2\>&1 \\** \ +> **(tar cf - . \\**\ +> ** \| pv -n -s \$(du -sb . \| awk \'{print \$1}\') \\**\ +> ** \| gzip -9 \> out.tgz) 2\>&1 \\**\ > **\| dialog \--gauge \'Progress\' 7 70** Taking an image of a disk, skipping errors: @@ -144,6 +144,12 @@ that are explicitly switched on will be shown. **-T**, and **-A**, and instead use the format string *FORMAT* to determine the output format. See the **FORMATTING** section below. +**-v, \--stats** + +: At the end of the transfer, write an additional line showing the + transfer rate minimum, maximum, mean, and standard deviation. The + values are always in bytes per second (or bits, with **-8**). + **-n, \--numeric** : Numeric output. Instead of giving a visual indication of progress, diff --git a/po/de.po b/po/de.po index 2380eeb..d3f40db 100644 --- a/po/de.po +++ b/po/de.po @@ -1,7 +1,7 @@ msgid "" msgstr "" "Report-Msgid-Bugs-To: pv@ivarch.com\n" -"POT-Creation-Date: 2024-10-04 13:27+0100\n" +"POT-Creation-Date: 2024-10-04 14:48+0100\n" "PO-Revision-Date: 2024-09-29 11:07+0000\n" "Last-Translator: a-j-wood \n" "Language-Team: German \n" @@ -50,7 +50,7 @@ msgstr "zeige die Datentransferrate an" msgid "show data transfer average rate counter" msgstr "zeige die durchschnittliche Übertragungsrate" -#: src/main/help.c:301 src/main/help.c:332 src/main/help.c:344 +#: src/main/help.c:301 src/main/help.c:335 src/main/help.c:347 msgid "SEC" msgstr "SEK" @@ -93,171 +93,175 @@ msgid "set output format to FORMAT" msgstr "setze das Ausgabeformat auf FORMAT" #: src/main/help.c:323 +msgid "output transfer statistics at the end" +msgstr "" + +#: src/main/help.c:326 msgid "output percentages, not visual information" msgstr "Ausgabe von Prozent-Angaben statt visueller Darstellung" -#: src/main/help.c:326 +#: src/main/help.c:329 msgid "do not output any transfer information at all" msgstr "sämtliche Transferinformationen unterdrücken" -#: src/main/help.c:330 +#: src/main/help.c:333 msgid "display nothing until first byte transferred" msgstr "keine Ausgabe bevor das erste Byte übertragen wurde" -#: src/main/help.c:333 +#: src/main/help.c:336 msgid "display nothing until SEC seconds have passed" msgstr "nichts anzeigen ehe SEK Sekunden vergangen sind" -#: src/main/help.c:335 +#: src/main/help.c:338 msgid "SIZE" msgstr "GRÖẞE" -#: src/main/help.c:336 +#: src/main/help.c:339 msgid "set estimated data size to SIZE bytes" msgstr "setze erwartete Datenlänge auf SIZE Byte" -#: src/main/help.c:339 +#: src/main/help.c:342 msgid "count lines instead of bytes" msgstr "zähle Zeilen anstelle von Bytes" -#: src/main/help.c:342 +#: src/main/help.c:345 msgid "lines are null-terminated" msgstr "Zeilen sind nullterminiert" -#: src/main/help.c:345 +#: src/main/help.c:348 msgid "update every SEC seconds" msgstr "aktualisiere Ausgabe nach SEK Sekunden Intervall" -#: src/main/help.c:347 +#: src/main/help.c:350 msgid "WIDTH" msgstr "BREITE" -#: src/main/help.c:348 +#: src/main/help.c:351 msgid "assume terminal is WIDTH characters wide" msgstr "setze Terminal-Breite auf BREITE Zeichen" -#: src/main/help.c:350 +#: src/main/help.c:353 msgid "HEIGHT" msgstr "HÖHE" -#: src/main/help.c:351 +#: src/main/help.c:354 msgid "assume terminal is HEIGHT rows high" msgstr "setze Terminal-Höhe auf HÖHE Zeichen" -#: src/main/help.c:353 +#: src/main/help.c:356 msgid "NAME" msgstr "NAME" -#: src/main/help.c:354 +#: src/main/help.c:357 msgid "prefix visual information with NAME" msgstr "setze den NAMEn für visuelle Darstellung" -#: src/main/help.c:357 +#: src/main/help.c:360 msgid "output even if standard error is not a terminal" msgstr "" "Ausgabe auch dann erzwingen, wenn der Fehlerausgabe-Kanal kein Terminal ist" -#: src/main/help.c:360 +#: src/main/help.c:363 msgid "use cursor positioning escape sequences" msgstr "benutze Escape-Sequenzen zur Cursor-Positionierung" -#: src/main/help.c:363 src/main/help.c:399 src/main/help.c:414 +#: src/main/help.c:366 src/main/help.c:402 src/main/help.c:417 msgid "FILE" msgstr "DATEI" -#: src/main/help.c:364 +#: src/main/help.c:367 msgid "write output to FILE instead of stdout" msgstr "schreibe die Ausgabe in DATEI statt in die Standardausgabe" -#: src/main/help.c:366 +#: src/main/help.c:369 msgid "RATE" msgstr "RATE" -#: src/main/help.c:367 +#: src/main/help.c:370 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 +#: src/main/help.c:372 src/main/help.c:381 msgid "BYTES" msgstr "BYTES" -#: src/main/help.c:370 +#: src/main/help.c:373 msgid "use a buffer size of BYTES" msgstr "benutze einen Puffer in der Größe von BYTES" -#: src/main/help.c:373 +#: src/main/help.c:376 msgid "never use splice(), always use read/write" msgstr "anstelle von splice() immer read/write benutzen" -#: src/main/help.c:376 +#: src/main/help.c:379 msgid "skip read errors in input" msgstr "Lesefehler in der Eingabe nicht beachten" -#: src/main/help.c:379 +#: src/main/help.c:382 msgid "skip errors in BYTES blocks at a time" msgstr "bei Fehlern BYTES am Stück überspringen" -#: src/main/help.c:382 +#: src/main/help.c:385 msgid "stop after --size bytes have been transferred" msgstr "anhalten, nachdem --size Bytes übertragen wurden" -#: src/main/help.c:385 +#: src/main/help.c:388 msgid "flush cache to disk after every write" msgstr "schreibe den Cache nach jedem Schreibvorgang auf die Festplatte" -#: src/main/help.c:388 +#: src/main/help.c:391 msgid "use direct I/O to bypass cache" msgstr "verwende direkte E/A, um den Cache zu umgehen" -#: src/main/help.c:391 +#: src/main/help.c:394 msgid "discard input instead of writing to output" msgstr "verwirf die Eingabe anstatt in die Ausgabe zu schreiben" -#: src/main/help.c:394 +#: src/main/help.c:397 msgid "PID" msgstr "PID" -#: src/main/help.c:395 +#: src/main/help.c:398 msgid "update settings of process PID" msgstr "Einstellungen der Prozess-PID updaten" -#: src/main/help.c:400 +#: src/main/help.c:403 msgid "save process ID in FILE" msgstr "Prozess-ID in DATEI speichern" -#: src/main/help.c:403 +#: src/main/help.c:406 msgid "PID[:FD]" msgstr "PID[:FD]" -#: src/main/help.c:404 +#: src/main/help.c:407 msgid "watch file FD opened by process PID" msgstr "die vom Prozess PID geöffnete Datei FD beobachten" -#: src/main/help.c:408 +#: src/main/help.c:411 msgid "show this help and exit" msgstr "zeige diese Hilfe und beende" -#: src/main/help.c:411 +#: src/main/help.c:414 msgid "show version information and exit" msgstr "zeige Versionsinformationen und beende" -#: src/main/help.c:415 +#: src/main/help.c:418 msgid "write debug logs to FILE" msgstr "schreibe Debug-Protokolle in DATEI" -#: src/main/help.c:440 +#: src/main/help.c:443 #, c-format msgid "Usage: %s [OPTION] [FILE]..." msgstr "Aufruf: %s [OPTION] [DATEI]..." -#: src/main/help.c:451 +#: src/main/help.c:454 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:588 +#: src/main/help.c:591 #, c-format msgid "Please report any bugs to: %s" msgstr "Bitte senden Sie Fehlerberichte an %s" @@ -290,41 +294,41 @@ msgstr "konnte Blockgerät nicht öffnen" msgid "failed to determine size of block device" msgstr "konnte Größe des Blockgeräts nicht ermitteln" -#: src/main/options.c:334 +#: src/main/options.c:335 msgid "option structure allocation failed" msgstr "Speicherzuweisung für `option' fehlgeschlagen" -#: src/main/options.c:353 +#: src/main/options.c:354 msgid "option structure argv allocation failed" msgstr "Speicherzuweisung für `argv' der Option fehlgeschlagen" -#: src/main/options.c:415 +#: src/main/options.c:416 msgid "integer argument expected" msgstr "Ganzzahliges Argument erwartet" -#: src/main/options.c:426 +#: src/main/options.c:427 msgid "numeric argument expected" msgstr "numerisches Argument erwartet" -#: src/main/options.c:437 +#: src/main/options.c:438 msgid "process ID or pid:fd pair expected" msgstr "Prozess-ID oder PID:FD-Paar erwartet" -#: src/main/options.c:444 +#: src/main/options.c:445 msgid "invalid process ID" msgstr "ungültige Prozess-ID" -#: src/main/options.c:647 +#: src/main/options.c:651 #, c-format msgid "Try `%s --help' for more information." msgstr "`%s --help' zeigt weitere Informationen an." -#: src/main/options.c:649 +#: src/main/options.c:653 #, c-format msgid "Try `%s -h' for more information." msgstr "`%s -h' zeigt weitere Informationen an." -#: src/main/options.c:680 +#: src/main/options.c:684 msgid "" "cannot use line mode or transfer modifier options when watching file " "descriptors" @@ -332,24 +336,24 @@ msgstr "" "Beim Beobachten von Dateideskriptoren können keine Optionen für den " "Zeilenmodus oder den Übertragungsmodifikator verwendet werden" -#: src/main/options.c:689 +#: src/main/options.c:693 msgid "cannot use cursor positioning when watching file descriptors" msgstr "" "Beim Beobachten von Dateideskriptoren kann Cursor-Positionierung nicht " "verwendet werden" -#: src/main/options.c:698 +#: src/main/options.c:702 msgid "cannot use remote control when watching file descriptors" msgstr "" "Beim Beobachten von Dateideskriptoren kann die Fernbedienung nicht verwenden " "werden" -#: src/main/options.c:707 +#: src/main/options.c:711 msgid "cannot transfer files when watching file descriptors" msgstr "" "Beim Beobachten von Dateideskriptoren können Dateien nicht übertragen werden" -#: src/main/options.c:722 +#: src/main/options.c:726 msgid "not available on systems without /proc/self/fdinfo" msgstr "Nicht verfügbar auf Systemen ohne /proc/self/fdinfo" @@ -401,31 +405,31 @@ msgstr "yzafpnµm kMGTPEZY" msgid "yzafpnum KMGTPEZY" msgstr "yzafpnµm KMGTPEZY" -#: src/pv/display.c:811 src/pv/transfer.c:970 +#: src/pv/display.c:829 src/pv/transfer.c:970 msgid "buffer allocation failed" msgstr "Speicherzuweisung für den Puffer fehlgeschlagen" -#: src/pv/display.c:920 +#: src/pv/display.c:938 msgid "b" msgstr "b" -#: src/pv/display.c:923 src/pv/transfer.c:602 +#: src/pv/display.c:941 src/pv/transfer.c:602 msgid "B" msgstr "B" -#: src/pv/display.c:967 src/pv/display.c:982 +#: src/pv/display.c:985 src/pv/display.c:1000 src/pv/loop.c:418 msgid "b/s" msgstr "b/s" -#: src/pv/display.c:971 src/pv/display.c:986 +#: src/pv/display.c:989 src/pv/display.c:1004 msgid "/s" msgstr "/s" -#: src/pv/display.c:971 src/pv/display.c:986 +#: src/pv/display.c:989 src/pv/display.c:1004 src/pv/loop.c:418 msgid "B/s" msgstr "B/s" -#: src/pv/display.c:1014 src/pv/display.c:1018 src/pv/display.c:1084 +#: src/pv/display.c:1032 src/pv/display.c:1036 src/pv/display.c:1102 msgid "ETA" msgstr "ETA" @@ -457,7 +461,15 @@ msgstr "(keine)" msgid "(stdin)" msgstr "(stdin)" -#: src/pv/loop.c:554 src/pv/loop.c:605 src/pv/loop.c:646 src/pv/watchpid.c:99 +#: src/pv/loop.c:417 +msgid "rate min/avg/max/mdev" +msgstr "" + +#: src/pv/loop.c:429 +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/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 @@ -469,7 +481,7 @@ msgstr "pid" msgid "history structure allocation failed" msgstr "Speicherzuweisung für `history' fehlgeschlagen" -#: src/pv/state.c:444 src/pv/state.c:455 +#: src/pv/state.c:465 src/pv/state.c:476 msgid "file list allocation failed" msgstr "Speicherzuweisung für die Dateiliste fehlgeschlagen" diff --git a/po/fr.po b/po/fr.po index 3ecc82a..7395194 100644 --- a/po/fr.po +++ b/po/fr.po @@ -1,7 +1,7 @@ msgid "" msgstr "" "Report-Msgid-Bugs-To: pv@ivarch.com\n" -"POT-Creation-Date: 2024-10-04 13:27+0100\n" +"POT-Creation-Date: 2024-10-04 14:48+0100\n" "Language: fr\n" "Content-Type: text/plain; charset=UTF-8\n" "Date: 1999-06-01 15:18:29+0100\n" @@ -44,7 +44,7 @@ msgstr "afficher le taux de tranfert des données" msgid "show data transfer average rate counter" msgstr "afficher le compteur de taux moyen de transfert de données" -#: src/main/help.c:301 src/main/help.c:332 src/main/help.c:344 +#: src/main/help.c:301 src/main/help.c:335 src/main/help.c:347 msgid "SEC" msgstr "SEC" @@ -86,171 +86,175 @@ msgid "set output format to FORMAT" msgstr "définir le format de sortie sur FORMAT" #: src/main/help.c:323 +msgid "output transfer statistics at the end" +msgstr "" + +#: src/main/help.c:326 msgid "output percentages, not visual information" msgstr "imprimer en pourcentage plutôt que des informations visuelles" -#: src/main/help.c:326 +#: src/main/help.c:329 msgid "do not output any transfer information at all" msgstr "n'afficher aucune information de transfert" -#: src/main/help.c:330 +#: src/main/help.c:333 msgid "display nothing until first byte transferred" msgstr "ne rien afficher avant qu'au moins un octet soit tranféré" -#: src/main/help.c:333 +#: src/main/help.c:336 msgid "display nothing until SEC seconds have passed" msgstr "ne rien afficher jusqu'à ce que SEC secondes se soient écoulées" -#: src/main/help.c:335 +#: src/main/help.c:338 msgid "SIZE" msgstr "TAILLE" -#: src/main/help.c:336 +#: src/main/help.c:339 msgid "set estimated data size to SIZE bytes" msgstr "ajuster la taille estimée des données à TAILLE octets" -#: src/main/help.c:339 +#: src/main/help.c:342 msgid "count lines instead of bytes" msgstr "compter les lignes au lieu des octets" -#: src/main/help.c:342 +#: src/main/help.c:345 msgid "lines are null-terminated" msgstr "les lignes sont terminées par un caractère nul" -#: src/main/help.c:345 +#: src/main/help.c:348 msgid "update every SEC seconds" msgstr "mettre à jour toutes les SEC secondes" -#: src/main/help.c:347 +#: src/main/help.c:350 msgid "WIDTH" msgstr "LARGEUR" -#: src/main/help.c:348 +#: src/main/help.c:351 msgid "assume terminal is WIDTH characters wide" msgstr "présumer la largeur du terminal à LARGEUR caractères" -#: src/main/help.c:350 +#: src/main/help.c:353 msgid "HEIGHT" msgstr "HAUTEUR" -#: src/main/help.c:351 +#: src/main/help.c:354 msgid "assume terminal is HEIGHT rows high" msgstr "présumer la hauteur du terminal à HAUTEUR lignes" -#: src/main/help.c:353 +#: src/main/help.c:356 msgid "NAME" msgstr "NOM" -#: src/main/help.c:354 +#: src/main/help.c:357 msgid "prefix visual information with NAME" msgstr "préfixer les informations visuelles avec NOM" -#: src/main/help.c:357 +#: src/main/help.c:360 msgid "output even if standard error is not a terminal" msgstr "" "imprimer vers la sortie d'erreur standard même si ce n'est pas un terminal" -#: src/main/help.c:360 +#: src/main/help.c:363 msgid "use cursor positioning escape sequences" msgstr "utiliser les séquences d'échappements de positionnement de curseur" -#: src/main/help.c:363 src/main/help.c:399 src/main/help.c:414 +#: src/main/help.c:366 src/main/help.c:402 src/main/help.c:417 msgid "FILE" msgstr "FICHIER" -#: src/main/help.c:364 +#: src/main/help.c:367 msgid "write output to FILE instead of stdout" msgstr "" -#: src/main/help.c:366 +#: src/main/help.c:369 msgid "RATE" msgstr "TAUX" -#: src/main/help.c:367 +#: src/main/help.c:370 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 +#: src/main/help.c:372 src/main/help.c:381 msgid "BYTES" msgstr "OCTETS" -#: src/main/help.c:370 +#: src/main/help.c:373 msgid "use a buffer size of BYTES" msgstr "Utiliser une mémoire tampon de OCTETS octets" -#: src/main/help.c:373 +#: src/main/help.c:376 msgid "never use splice(), always use read/write" msgstr "ne jamais utiliser splice(), toujours utiliser read/write" -#: src/main/help.c:376 +#: src/main/help.c:379 msgid "skip read errors in input" msgstr "ignorer les erreurs de lecture dans l'entrée" -#: src/main/help.c:379 +#: src/main/help.c:382 msgid "skip errors in BYTES blocks at a time" msgstr "ignorer les erreurs dans OCTETS blocs à la fois" -#: src/main/help.c:382 +#: src/main/help.c:385 msgid "stop after --size bytes have been transferred" msgstr "arrêter après le transfert de --size octets" -#: src/main/help.c:385 +#: src/main/help.c:388 msgid "flush cache to disk after every write" msgstr "vider le cache sur le disque après chaque écriture" -#: src/main/help.c:388 +#: src/main/help.c:391 msgid "use direct I/O to bypass cache" msgstr "utiliser les E/S directes pour contourner le cache" -#: src/main/help.c:391 +#: src/main/help.c:394 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 +#: src/main/help.c:397 msgid "PID" msgstr "PID" -#: src/main/help.c:395 +#: src/main/help.c:398 msgid "update settings of process PID" msgstr "mettre à jour la configuration du processus PID" -#: src/main/help.c:400 +#: src/main/help.c:403 msgid "save process ID in FILE" msgstr "enregistrer l'ID de processus dans FICHIER" -#: src/main/help.c:403 +#: src/main/help.c:406 msgid "PID[:FD]" msgstr "PID[:FD]" -#: src/main/help.c:404 +#: src/main/help.c:407 msgid "watch file FD opened by process PID" msgstr "surveiller le fichier FD ouvert par le processus PID" -#: src/main/help.c:408 +#: src/main/help.c:411 msgid "show this help and exit" msgstr "afficher cette aide puis quitter" -#: src/main/help.c:411 +#: src/main/help.c:414 msgid "show version information and exit" msgstr "afficher la version puis quitter" -#: src/main/help.c:415 +#: src/main/help.c:418 msgid "write debug logs to FILE" msgstr "écrire les journaux de déboggage vers FICHIER" -#: src/main/help.c:440 +#: src/main/help.c:443 #, c-format msgid "Usage: %s [OPTION] [FILE]..." msgstr "Utilisation : %s [OPTIONS] [FICHIER]..." -#: src/main/help.c:451 +#: src/main/help.c:454 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:588 +#: src/main/help.c:591 #, c-format msgid "Please report any bugs to: %s" msgstr "SVP rapporter tous bogues à %s" @@ -283,41 +287,41 @@ msgstr "" msgid "failed to determine size of block device" msgstr "" -#: src/main/options.c:334 +#: src/main/options.c:335 msgid "option structure allocation failed" msgstr "l'allocation pour la structure d'une option a échoué" -#: src/main/options.c:353 +#: src/main/options.c:354 msgid "option structure argv allocation failed" msgstr "l'allocation pour la structure de l'option argv a échoué" -#: src/main/options.c:415 +#: src/main/options.c:416 msgid "integer argument expected" msgstr "Valeur entière attendue" -#: src/main/options.c:426 +#: src/main/options.c:427 msgid "numeric argument expected" msgstr "Valeur numérique attendue" -#: src/main/options.c:437 +#: src/main/options.c:438 msgid "process ID or pid:fd pair expected" msgstr "ID de processus ou paire pid:fd attendue" -#: src/main/options.c:444 +#: src/main/options.c:445 msgid "invalid process ID" msgstr "ID de processus non valide" -#: src/main/options.c:647 +#: src/main/options.c:651 #, c-format msgid "Try `%s --help' for more information." msgstr "Essayez `%s --help' pour plus d'informations." -#: src/main/options.c:649 +#: src/main/options.c:653 #, c-format msgid "Try `%s -h' for more information." msgstr "Essayez `%s -h' pour plus d'informations." -#: src/main/options.c:680 +#: src/main/options.c:684 msgid "" "cannot use line mode or transfer modifier options when watching file " "descriptors" @@ -325,25 +329,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:689 +#: src/main/options.c:693 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:698 +#: src/main/options.c:702 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:707 +#: src/main/options.c:711 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:722 +#: src/main/options.c:726 msgid "not available on systems without /proc/self/fdinfo" msgstr "non disponible sur les systèmes sans /proc/self/fdinfo" @@ -397,31 +401,31 @@ msgstr "" msgid "yzafpnum KMGTPEZY" msgstr "" -#: src/pv/display.c:811 src/pv/transfer.c:970 +#: src/pv/display.c:829 src/pv/transfer.c:970 msgid "buffer allocation failed" msgstr "échec de l'allocation de mémoire tampon" -#: src/pv/display.c:920 +#: src/pv/display.c:938 msgid "b" msgstr "" -#: src/pv/display.c:923 src/pv/transfer.c:602 +#: src/pv/display.c:941 src/pv/transfer.c:602 msgid "B" msgstr "O" -#: src/pv/display.c:967 src/pv/display.c:982 +#: src/pv/display.c:985 src/pv/display.c:1000 src/pv/loop.c:418 msgid "b/s" msgstr "" -#: src/pv/display.c:971 src/pv/display.c:986 +#: src/pv/display.c:989 src/pv/display.c:1004 msgid "/s" msgstr "/s" -#: src/pv/display.c:971 src/pv/display.c:986 +#: src/pv/display.c:989 src/pv/display.c:1004 src/pv/loop.c:418 msgid "B/s" msgstr "O/s" -#: src/pv/display.c:1014 src/pv/display.c:1018 src/pv/display.c:1084 +#: src/pv/display.c:1032 src/pv/display.c:1036 src/pv/display.c:1102 msgid "ETA" msgstr "ETA" @@ -453,7 +457,15 @@ msgstr "(aucun)" msgid "(stdin)" msgstr "" -#: src/pv/loop.c:554 src/pv/loop.c:605 src/pv/loop.c:646 src/pv/watchpid.c:99 +#: src/pv/loop.c:417 +msgid "rate min/avg/max/mdev" +msgstr "" + +#: src/pv/loop.c:429 +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/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 @@ -465,7 +477,7 @@ msgstr "" msgid "history structure allocation failed" msgstr "l'allocation de la structure de l'historique a échoué" -#: src/pv/state.c:444 src/pv/state.c:455 +#: src/pv/state.c:465 src/pv/state.c:476 msgid "file list allocation failed" msgstr "échec de l'allocation de la liste de fichiers" diff --git a/po/pl.po b/po/pl.po index 605eb62..cb29e10 100644 --- a/po/pl.po +++ b/po/pl.po @@ -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 13:27+0100\n" +"POT-Creation-Date: 2024-10-04 14:48+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -39,7 +39,7 @@ msgstr "pokaż licznik prędkości przesyłania" msgid "show data transfer average rate counter" msgstr "" -#: src/main/help.c:301 src/main/help.c:332 src/main/help.c:344 +#: src/main/help.c:301 src/main/help.c:335 src/main/help.c:347 msgid "SEC" msgstr "WARTOŚĆ" @@ -80,170 +80,174 @@ msgid "set output format to FORMAT" msgstr "" #: src/main/help.c:323 +msgid "output transfer statistics at the end" +msgstr "" + +#: src/main/help.c:326 msgid "output percentages, not visual information" msgstr "wświetl wyjście procentowo, bez graficznej prezentacji" -#: src/main/help.c:326 +#: src/main/help.c:329 msgid "do not output any transfer information at all" msgstr "nie wyświetlaj żadnych informacji o przesyłaniu" -#: src/main/help.c:330 +#: src/main/help.c:333 msgid "display nothing until first byte transferred" msgstr "nie wyświetlaj nic aż do pierwszego przesłanego bajtu" -#: src/main/help.c:333 +#: src/main/help.c:336 msgid "display nothing until SEC seconds have passed" msgstr "" -#: src/main/help.c:335 +#: src/main/help.c:338 msgid "SIZE" msgstr "WARTOŚĆ" -#: src/main/help.c:336 +#: src/main/help.c:339 msgid "set estimated data size to SIZE bytes" msgstr "ustaw oczekiwany rozmiar danych na WARTOŚĆ bajtów" -#: src/main/help.c:339 +#: src/main/help.c:342 msgid "count lines instead of bytes" msgstr "" -#: src/main/help.c:342 +#: src/main/help.c:345 msgid "lines are null-terminated" msgstr "" -#: src/main/help.c:345 +#: src/main/help.c:348 msgid "update every SEC seconds" msgstr "aktualizuj co każde WARTOŚĆ sekund" -#: src/main/help.c:347 +#: src/main/help.c:350 msgid "WIDTH" msgstr "WARTOŚĆ" -#: src/main/help.c:348 +#: src/main/help.c:351 msgid "assume terminal is WIDTH characters wide" msgstr "przyjmij, że terminal ma szerokość WARTOŚĆ znaków" -#: src/main/help.c:350 +#: src/main/help.c:353 msgid "HEIGHT" msgstr "" -#: src/main/help.c:351 +#: src/main/help.c:354 msgid "assume terminal is HEIGHT rows high" msgstr "przyjmij, że terminal ma szerokość WARTOŚĆ znaków" -#: src/main/help.c:353 +#: src/main/help.c:356 msgid "NAME" msgstr "NAZWA" -#: src/main/help.c:354 +#: src/main/help.c:357 msgid "prefix visual information with NAME" msgstr "poprzedź informacje prefiksem NAZWA" -#: src/main/help.c:357 +#: src/main/help.c:360 msgid "output even if standard error is not a terminal" msgstr "pokaż wyjście nawet gdy błędy nie są typu terminal" -#: src/main/help.c:360 +#: src/main/help.c:363 msgid "use cursor positioning escape sequences" msgstr "używaj sekwencji escape do pozycjonowania" -#: src/main/help.c:363 src/main/help.c:399 src/main/help.c:414 +#: src/main/help.c:366 src/main/help.c:402 src/main/help.c:417 msgid "FILE" msgstr "" -#: src/main/help.c:364 +#: src/main/help.c:367 msgid "write output to FILE instead of stdout" msgstr "" -#: src/main/help.c:366 +#: src/main/help.c:369 msgid "RATE" msgstr "" -#: src/main/help.c:367 +#: src/main/help.c:370 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 +#: src/main/help.c:372 src/main/help.c:381 msgid "BYTES" msgstr "" -#: src/main/help.c:370 +#: src/main/help.c:373 msgid "use a buffer size of BYTES" msgstr "" -#: src/main/help.c:373 +#: src/main/help.c:376 msgid "never use splice(), always use read/write" msgstr "" -#: src/main/help.c:376 +#: src/main/help.c:379 msgid "skip read errors in input" msgstr "" -#: src/main/help.c:379 +#: src/main/help.c:382 msgid "skip errors in BYTES blocks at a time" msgstr "" -#: src/main/help.c:382 +#: src/main/help.c:385 msgid "stop after --size bytes have been transferred" msgstr "" -#: src/main/help.c:385 +#: src/main/help.c:388 msgid "flush cache to disk after every write" msgstr "" -#: src/main/help.c:388 +#: src/main/help.c:391 msgid "use direct I/O to bypass cache" msgstr "" -#: src/main/help.c:391 +#: src/main/help.c:394 msgid "discard input instead of writing to output" msgstr "" -#: src/main/help.c:394 +#: src/main/help.c:397 msgid "PID" msgstr "" -#: src/main/help.c:395 +#: src/main/help.c:398 msgid "update settings of process PID" msgstr "" -#: src/main/help.c:400 +#: src/main/help.c:403 msgid "save process ID in FILE" msgstr "" -#: src/main/help.c:403 +#: src/main/help.c:406 msgid "PID[:FD]" msgstr "" -#: src/main/help.c:404 +#: src/main/help.c:407 msgid "watch file FD opened by process PID" msgstr "" -#: src/main/help.c:408 +#: src/main/help.c:411 msgid "show this help and exit" msgstr "wyświetl te informacje z pomocą i wyjdź" -#: src/main/help.c:411 +#: src/main/help.c:414 msgid "show version information and exit" msgstr "wyświetl informacje o wersji i wyjdź" -#: src/main/help.c:415 +#: src/main/help.c:418 msgid "write debug logs to FILE" msgstr "" -#: src/main/help.c:440 +#: src/main/help.c:443 #, c-format msgid "Usage: %s [OPTION] [FILE]..." msgstr "Sposób użycia: %s [OPCJA] [PLIK]..." -#: src/main/help.c:451 +#: src/main/help.c:454 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:588 +#: src/main/help.c:591 #, c-format msgid "Please report any bugs to: %s" msgstr "Proszę przesyłać zgłoszenia błędów do %s" @@ -276,59 +280,59 @@ msgstr "" msgid "failed to determine size of block device" msgstr "" -#: src/main/options.c:334 +#: src/main/options.c:335 msgid "option structure allocation failed" msgstr "nie udało się zaalokować struktur opcji" -#: src/main/options.c:353 +#: src/main/options.c:354 msgid "option structure argv allocation failed" msgstr "nie udało się zaalokować struktur opcji argv" -#: src/main/options.c:415 +#: src/main/options.c:416 msgid "integer argument expected" msgstr "" -#: src/main/options.c:426 +#: src/main/options.c:427 msgid "numeric argument expected" msgstr "" -#: src/main/options.c:437 +#: src/main/options.c:438 msgid "process ID or pid:fd pair expected" msgstr "" -#: src/main/options.c:444 +#: src/main/options.c:445 msgid "invalid process ID" msgstr "" -#: src/main/options.c:647 +#: src/main/options.c:651 #, c-format msgid "Try `%s --help' for more information." msgstr "Spróbuj `%s --help' by uzyskać więcej informacji" -#: src/main/options.c:649 +#: src/main/options.c:653 #, c-format msgid "Try `%s -h' for more information." msgstr "Spróbuj `%s -h' by uzyskać więcej informacji" -#: src/main/options.c:680 +#: src/main/options.c:684 msgid "" "cannot use line mode or transfer modifier options when watching file " "descriptors" msgstr "" -#: src/main/options.c:689 +#: src/main/options.c:693 msgid "cannot use cursor positioning when watching file descriptors" msgstr "" -#: src/main/options.c:698 +#: src/main/options.c:702 msgid "cannot use remote control when watching file descriptors" msgstr "" -#: src/main/options.c:707 +#: src/main/options.c:711 msgid "cannot transfer files when watching file descriptors" msgstr "" -#: src/main/options.c:722 +#: src/main/options.c:726 msgid "not available on systems without /proc/self/fdinfo" msgstr "" @@ -381,31 +385,31 @@ msgstr "" msgid "yzafpnum KMGTPEZY" msgstr "" -#: src/pv/display.c:811 src/pv/transfer.c:970 +#: src/pv/display.c:829 src/pv/transfer.c:970 msgid "buffer allocation failed" msgstr "nie udało się zaalokować bufora" -#: src/pv/display.c:920 +#: src/pv/display.c:938 msgid "b" msgstr "" -#: src/pv/display.c:923 src/pv/transfer.c:602 +#: src/pv/display.c:941 src/pv/transfer.c:602 msgid "B" msgstr "B" -#: src/pv/display.c:967 src/pv/display.c:982 +#: src/pv/display.c:985 src/pv/display.c:1000 src/pv/loop.c:418 msgid "b/s" msgstr "" -#: src/pv/display.c:971 src/pv/display.c:986 +#: src/pv/display.c:989 src/pv/display.c:1004 msgid "/s" msgstr "/s" -#: src/pv/display.c:971 src/pv/display.c:986 +#: src/pv/display.c:989 src/pv/display.c:1004 src/pv/loop.c:418 msgid "B/s" msgstr "B/s" -#: src/pv/display.c:1014 src/pv/display.c:1018 src/pv/display.c:1084 +#: src/pv/display.c:1032 src/pv/display.c:1036 src/pv/display.c:1102 msgid "ETA" msgstr "ETA" @@ -438,7 +442,15 @@ msgstr "" msgid "(stdin)" msgstr "" -#: src/pv/loop.c:554 src/pv/loop.c:605 src/pv/loop.c:646 src/pv/watchpid.c:99 +#: src/pv/loop.c:417 +msgid "rate min/avg/max/mdev" +msgstr "" + +#: src/pv/loop.c:429 +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/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 @@ -450,7 +462,7 @@ msgstr "" msgid "history structure allocation failed" msgstr "" -#: src/pv/state.c:444 src/pv/state.c:455 +#: src/pv/state.c:465 src/pv/state.c:476 msgid "file list allocation failed" msgstr "" diff --git a/po/pt.po b/po/pt.po index d7e05f1..ae418b3 100644 --- a/po/pt.po +++ b/po/pt.po @@ -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 13:27+0100\n" +"POT-Creation-Date: 2024-10-04 14:48+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -39,7 +39,7 @@ msgstr "exibe a taxa de transferência" msgid "show data transfer average rate counter" msgstr "exibe o contador da taxa média de transferência de dados" -#: src/main/help.c:301 src/main/help.c:332 src/main/help.c:344 +#: src/main/help.c:301 src/main/help.c:335 src/main/help.c:347 msgid "SEC" msgstr "" @@ -80,170 +80,174 @@ msgid "set output format to FORMAT" msgstr "definir o formato de saída para FORMAT" #: src/main/help.c:323 +msgid "output transfer statistics at the end" +msgstr "" + +#: src/main/help.c:326 msgid "output percentages, not visual information" msgstr "exibe apenas as porcentagens, sem informações visuais" -#: src/main/help.c:326 +#: src/main/help.c:329 msgid "do not output any transfer information at all" msgstr "executa programa sem exibir quaisquer informações" -#: src/main/help.c:330 +#: src/main/help.c:333 msgid "display nothing until first byte transferred" msgstr "não exibe nada até iniciar o processamento" -#: src/main/help.c:333 +#: src/main/help.c:336 msgid "display nothing until SEC seconds have passed" msgstr "não exibir nada até que os segundos SEC tenham passado" -#: src/main/help.c:335 +#: src/main/help.c:338 msgid "SIZE" msgstr "" -#: src/main/help.c:336 +#: src/main/help.c:339 msgid "set estimated data size to SIZE bytes" msgstr "seta a quantidade estimada de dados em SIZE bytes" -#: src/main/help.c:339 +#: src/main/help.c:342 msgid "count lines instead of bytes" msgstr "contar linhas em vez de bytes" -#: src/main/help.c:342 +#: src/main/help.c:345 msgid "lines are null-terminated" msgstr "linhas são terminadas em nulo" -#: src/main/help.c:345 +#: src/main/help.c:348 msgid "update every SEC seconds" msgstr "atualiza informações a cada SEC segundos" -#: src/main/help.c:347 +#: src/main/help.c:350 msgid "WIDTH" msgstr "" -#: src/main/help.c:348 +#: src/main/help.c:351 msgid "assume terminal is WIDTH characters wide" msgstr "presuma que o terminal tem WIDTH caracteres de largura" -#: src/main/help.c:350 +#: src/main/help.c:353 msgid "HEIGHT" msgstr "" -#: src/main/help.c:351 +#: src/main/help.c:354 msgid "assume terminal is HEIGHT rows high" msgstr "presuma que o terminal tem HEIGHT caracteres de altura" -#: src/main/help.c:353 +#: src/main/help.c:356 msgid "NAME" msgstr "" -#: src/main/help.c:354 +#: src/main/help.c:357 msgid "prefix visual information with NAME" msgstr "exibe NAME antes das demais informações" -#: src/main/help.c:357 +#: src/main/help.c:360 msgid "output even if standard error is not a terminal" msgstr "gera dados mesmo que a saída de erro seja redirecionada" -#: src/main/help.c:360 +#: src/main/help.c:363 msgid "use cursor positioning escape sequences" msgstr "utiliza caracteres de escape para posicionar o cursor" -#: src/main/help.c:363 src/main/help.c:399 src/main/help.c:414 +#: src/main/help.c:366 src/main/help.c:402 src/main/help.c:417 msgid "FILE" msgstr "" -#: src/main/help.c:364 +#: src/main/help.c:367 msgid "write output to FILE instead of stdout" msgstr "" -#: src/main/help.c:366 +#: src/main/help.c:369 msgid "RATE" msgstr "" -#: src/main/help.c:367 +#: src/main/help.c:370 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 +#: src/main/help.c:372 src/main/help.c:381 msgid "BYTES" msgstr "" -#: src/main/help.c:370 +#: src/main/help.c:373 msgid "use a buffer size of BYTES" msgstr "use um tamanho de buffer de BYTES" -#: src/main/help.c:373 +#: src/main/help.c:376 msgid "never use splice(), always use read/write" msgstr "nunca use splice(), sempre use read/write" -#: src/main/help.c:376 +#: src/main/help.c:379 msgid "skip read errors in input" msgstr "ignorar erros de leitura em entrada" -#: src/main/help.c:379 +#: src/main/help.c:382 msgid "skip errors in BYTES blocks at a time" msgstr "" -#: src/main/help.c:382 +#: src/main/help.c:385 msgid "stop after --size bytes have been transferred" msgstr "parar após --size bytes terem sido transferidos" -#: src/main/help.c:385 +#: src/main/help.c:388 msgid "flush cache to disk after every write" msgstr "" -#: src/main/help.c:388 +#: src/main/help.c:391 msgid "use direct I/O to bypass cache" msgstr "" -#: src/main/help.c:391 +#: src/main/help.c:394 msgid "discard input instead of writing to output" msgstr "" -#: src/main/help.c:394 +#: src/main/help.c:397 msgid "PID" msgstr "" -#: src/main/help.c:395 +#: src/main/help.c:398 msgid "update settings of process PID" msgstr "atualizar as configurações do processo PID" -#: src/main/help.c:400 +#: src/main/help.c:403 msgid "save process ID in FILE" msgstr "salvar ID do processo em FILE" -#: src/main/help.c:403 +#: src/main/help.c:406 msgid "PID[:FD]" msgstr "" -#: src/main/help.c:404 +#: src/main/help.c:407 msgid "watch file FD opened by process PID" msgstr "assistir arquivo FD aberto pelo processo PID" -#: src/main/help.c:408 +#: src/main/help.c:411 msgid "show this help and exit" msgstr "exibe esta tela de ajuda e termina" -#: src/main/help.c:411 +#: src/main/help.c:414 msgid "show version information and exit" msgstr "exibe a versão e termina" -#: src/main/help.c:415 +#: src/main/help.c:418 msgid "write debug logs to FILE" msgstr "" -#: src/main/help.c:440 +#: src/main/help.c:443 #, c-format msgid "Usage: %s [OPTION] [FILE]..." msgstr "Uso: %s [OPÇÕES] [ARQUIVOS]..." -#: src/main/help.c:451 +#: src/main/help.c:454 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:588 +#: src/main/help.c:591 #, c-format msgid "Please report any bugs to: %s" msgstr "Por favor, reporte quaisquer defeitos para %s" @@ -276,41 +280,41 @@ msgstr "" msgid "failed to determine size of block device" msgstr "" -#: src/main/options.c:334 +#: src/main/options.c:335 msgid "option structure allocation failed" msgstr "erro na alocação da estrutura de opções" -#: src/main/options.c:353 +#: src/main/options.c:354 msgid "option structure argv allocation failed" msgstr "erro na alocação da estrutura de opções argv" -#: src/main/options.c:415 +#: src/main/options.c:416 msgid "integer argument expected" msgstr "argumento inteiro esperado" -#: src/main/options.c:426 +#: src/main/options.c:427 msgid "numeric argument expected" msgstr "argumento numérico esperado" -#: src/main/options.c:437 +#: src/main/options.c:438 msgid "process ID or pid:fd pair expected" msgstr "ID do processo ou par pid:fd esperado" -#: src/main/options.c:444 +#: src/main/options.c:445 msgid "invalid process ID" msgstr "ID de processo inválido" -#: src/main/options.c:647 +#: src/main/options.c:651 #, c-format msgid "Try `%s --help' for more information." msgstr "Tente `%s --help' para maiores informações." -#: src/main/options.c:649 +#: src/main/options.c:653 #, c-format msgid "Try `%s -h' for more information." msgstr "Tente `%s -h' para maiores informações." -#: src/main/options.c:680 +#: src/main/options.c:684 msgid "" "cannot use line mode or transfer modifier options when watching file " "descriptors" @@ -318,21 +322,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:689 +#: src/main/options.c:693 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:698 +#: src/main/options.c:702 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:707 +#: src/main/options.c:711 msgid "cannot transfer files when watching file descriptors" msgstr "não pode transferir arquivos ao assistir descritores de arquivo" -#: src/main/options.c:722 +#: src/main/options.c:726 msgid "not available on systems without /proc/self/fdinfo" msgstr "não disponível em sistemas sem /proc/self/fdinfo" @@ -384,31 +388,31 @@ msgstr "" msgid "yzafpnum KMGTPEZY" msgstr "" -#: src/pv/display.c:811 src/pv/transfer.c:970 +#: src/pv/display.c:829 src/pv/transfer.c:970 msgid "buffer allocation failed" msgstr "erro alocando o buffer" -#: src/pv/display.c:920 +#: src/pv/display.c:938 msgid "b" msgstr "" -#: src/pv/display.c:923 src/pv/transfer.c:602 +#: src/pv/display.c:941 src/pv/transfer.c:602 msgid "B" msgstr "" -#: src/pv/display.c:967 src/pv/display.c:982 +#: src/pv/display.c:985 src/pv/display.c:1000 src/pv/loop.c:418 msgid "b/s" msgstr "" -#: src/pv/display.c:971 src/pv/display.c:986 +#: src/pv/display.c:989 src/pv/display.c:1004 msgid "/s" msgstr "" -#: src/pv/display.c:971 src/pv/display.c:986 +#: src/pv/display.c:989 src/pv/display.c:1004 src/pv/loop.c:418 msgid "B/s" msgstr "B/s" -#: src/pv/display.c:1014 src/pv/display.c:1018 src/pv/display.c:1084 +#: src/pv/display.c:1032 src/pv/display.c:1036 src/pv/display.c:1102 msgid "ETA" msgstr "ETA" @@ -440,7 +444,15 @@ msgstr "" msgid "(stdin)" msgstr "" -#: src/pv/loop.c:554 src/pv/loop.c:605 src/pv/loop.c:646 src/pv/watchpid.c:99 +#: src/pv/loop.c:417 +msgid "rate min/avg/max/mdev" +msgstr "" + +#: src/pv/loop.c:429 +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/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 @@ -452,7 +464,7 @@ msgstr "" msgid "history structure allocation failed" msgstr "" -#: src/pv/state.c:444 src/pv/state.c:455 +#: src/pv/state.c:465 src/pv/state.c:476 msgid "file list allocation failed" msgstr "" diff --git a/src/include/config.h.in b/src/include/config.h.in index a1d7d9f..5ba8d90 100644 --- a/src/include/config.h.in +++ b/src/include/config.h.in @@ -73,6 +73,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_LOCALE_H +/* Define to 1 if you have the header file. */ +#undef HAVE_MATH_H + /* Define to 1 if you have the `memcpy' function. */ #undef HAVE_MEMCPY @@ -112,6 +115,9 @@ /* Define to 1 if you have the `splice' function. */ #undef HAVE_SPLICE +/* Define to 1 if you have the `sqrtl' function. */ +#undef HAVE_SQRTL + /* Define to 1 if stdbool.h conforms to C99. */ #undef HAVE_STDBOOL_H diff --git a/src/include/options.h b/src/include/options.h index c28f7be..a793039 100644 --- a/src/include/options.h +++ b/src/include/options.h @@ -74,6 +74,7 @@ struct opts_s { 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 output */ + bool show_stats; /* set to write statistics at the end */ bool width_set_manually; /* width was set manually, not detected */ bool height_set_manually; /* height was set manually, not detected */ }; diff --git a/src/include/pv-internal.h b/src/include/pv-internal.h index 2c0d43a..05d7708 100644 --- a/src/include/pv-internal.h +++ b/src/include/pv-internal.h @@ -134,6 +134,7 @@ struct pvstate_s { bool direct_io_changed; /* set when direct_io is changed */ bool no_splice; /* never use splice() */ bool discard_input; /* write nothing to stdout */ + bool show_stats; /* show statistics on exit */ bool width_set_manually; /* width was set manually, not detected */ bool height_set_manually; /* height was set manually, not detected */ } control; @@ -219,6 +220,12 @@ struct pvstate_s { long double prev_trans; /* amount transferred since last rate calculation */ long double current_avg_rate; /* current average rate over last history intervals */ + long double rate_min; /* minimum measured transfer rate */ + long double rate_max; /* maximum measured transfer rate */ + long double rate_sum; /* sum of all measured transfer rates */ + long double ratesquared_sum; /* sum of the squares of each transfer rate */ + unsigned long measurements_taken; /* how many times the rate was measured */ + /* Keep track of progress over last intervals to compute current average rate. */ /*@null@*/ struct { /* state at previous intervals (circular buffer) */ long double elapsed_sec; /* time since start of transfer */ diff --git a/src/include/pv.h b/src/include/pv.h index d75106a..74971d2 100644 --- a/src/include/pv.h +++ b/src/include/pv.h @@ -172,6 +172,7 @@ extern void pv_state_set_format(pvstate_t state, bool progress, */ extern void pv_state_force_set(pvstate_t, bool); extern void pv_state_cursor_set(pvstate_t, bool); +extern void pv_state_show_stats_set(pvstate_t, bool); extern void pv_state_numeric_set(pvstate_t, bool); extern void pv_state_wait_set(pvstate_t, bool); extern void pv_state_delay_start_set(pvstate_t, double); diff --git a/src/main/help.c b/src/main/help.c index 0a3eb88..4c9dc80 100644 --- a/src/main/help.c +++ b/src/main/help.c @@ -319,6 +319,9 @@ void display_help(void) { "-F", "--format", N_("FORMAT"), N_("set output format to FORMAT"), { 0, 0, 0, 0} }, + { "-v", "--stats", NULL, + N_("output transfer statistics at the end"), + { 0, 0, 0, 0} }, { "-n", "--numeric", NULL, N_("output percentages, not visual information"), { 0, 0, 0, 0} }, diff --git a/src/main/main.c b/src/main/main.c index 693cac9..213c418 100644 --- a/src/main/main.c +++ b/src/main/main.c @@ -306,6 +306,7 @@ int main(int argc, char **argv) pv_state_no_display_set(state, opts->no_display); pv_state_force_set(state, opts->force); pv_state_cursor_set(state, opts->cursor); + pv_state_show_stats_set(state, opts->show_stats); pv_state_numeric_set(state, opts->numeric); pv_state_wait_set(state, opts->wait); pv_state_delay_start_set(state, opts->delay_start); diff --git a/src/main/options.c b/src/main/options.c index b2c375f..91e5635 100644 --- a/src/main/options.c +++ b/src/main/options.c @@ -290,6 +290,7 @@ opts_t opts_parse(unsigned int argc, char **argv) { "height", 1, NULL, (int) 'H' }, { "name", 1, NULL, (int) 'N' }, { "format", 1, NULL, (int) 'F' }, + { "stats", 0, NULL, (int) 'v' }, { "rate-limit", 1, NULL, (int) 'L' }, { "buffer-size", 1, NULL, (int) 'B' }, { "no-splice", 0, NULL, (int) 'C' }, @@ -312,7 +313,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:o:" + char *short_options = "hVpteIrab8kTA:fvnqcWD:s:l0i:w:H:N:F:L:B:CEZ:SYKXR:P:d:m:o:" #ifdef ENABLE_DEBUGGING "!:" #endif @@ -512,6 +513,9 @@ opts_t opts_parse(unsigned int argc, char **argv) case 'f': opts->force = true; break; + case 'v': + opts->show_stats = true; + break; case 'n': opts->numeric = true; numopts++; diff --git a/src/pv/display.c b/src/pv/display.c index 269204c..320b542 100644 --- a/src/pv/display.c +++ b/src/pv/display.c @@ -694,6 +694,24 @@ void pv_calculate_transfer_rate(pvstate_t state, bool final) transfer_rate = ((long double) bytes_since_last + state->calc.prev_trans) / time_since_last; state->calc.prev_elapsed_sec = state->transfer.elapsed_seconds; state->calc.prev_trans = 0; + + /* Maintain information for statistics. */ + if (state->control.show_stats) { + long double measured_rate = transfer_rate; + + if (state->control.bits) + measured_rate = 8.0 * measured_rate; + + if ((state->calc.measurements_taken < 1) || (measured_rate < state->calc.rate_min)) { + state->calc.rate_min = measured_rate; + } + if (measured_rate > state->calc.rate_max) { + state->calc.rate_max = measured_rate; + } + state->calc.rate_sum += measured_rate; + state->calc.ratesquared_sum += (measured_rate * measured_rate); + state->calc.measurements_taken++; + } } state->calc.prev_rate = transfer_rate; diff --git a/src/pv/loop.c b/src/pv/loop.c index 726c649..e71b130 100644 --- a/src/pv/loop.c +++ b/src/pv/loop.c @@ -24,6 +24,32 @@ #include #include +#if HAVE_MATH_H +#include +#endif + + +#if HAVE_SQRTL +#else +/* + * Square root of a long double. Adapted from iputils ping/ping_common.c. + */ +static long ldsqrt(long double value) +{ + long double previous = (long double) LLONG_MAX; + long double result = value; + + if (result > 0) { + while (result < previous) { + previous = result; + result = (result + (value / result)) / 2; + } + } + + return result; +} +#endif + /* * Pipe data from a list of files to standard output, giving information @@ -243,8 +269,11 @@ int pv_main_loop(pvstate_t state) } } - /* Just go round the loop again if there's no display. */ - if (state->control.no_display) + /* + * Just go round the loop again if there's no display and + * we're not reporting statistics. + */ + if (state->control.no_display && !state->control.show_stats) continue; /* @@ -331,7 +360,13 @@ int pv_main_loop(pvstate_t state) state->control.height = new_height; } - pv_display(state, final_update); + if (state->control.no_display) { + /* If there's no display, calculate rate for the statistics. */ + pv_calculate_transfer_rate(state, final_update); + } else { + /* Produce the display. */ + pv_display(state, final_update); + } } debug("%s: %s=%s, %s=%s", "loop ended", "eof_in", eof_in ? "true" : "false", "eof_out", @@ -351,6 +386,52 @@ int pv_main_loop(pvstate_t state) if (fd >= 0) (void) close(fd); + /* Calculate and display the transfer statistics. */ + if (state->control.show_stats && state->calc.measurements_taken > 0) { + char stats_buf[256]; /* flawfinder: ignore */ + long double rate_mean, rate_variance, rate_deviation; + int stats_size; + + /* flawfinder: made safe by use of pv_snprintf() */ + + rate_mean = state->calc.rate_sum / ((long double) (state->calc.measurements_taken)); + rate_variance = + (state->calc.ratesquared_sum / ((long double) (state->calc.measurements_taken))) - + (rate_mean * rate_mean); +#if HAVE_SQRTL + rate_deviation = sqrtl(rate_variance); +#else + rate_deviation = ldsqrt(rate_variance); +#endif + + debug("%s: %ld", "measurements taken", state->calc.measurements_taken); + debug("%s: %.3Lf", "rate_sum", state->calc.rate_sum); + debug("%s: %.3Lf", "ratesquared_sum", state->calc.ratesquared_sum); + debug("%s: %.3Lf", "rate_mean", rate_mean); + debug("%s: %.3Lf", "rate_variance", rate_variance); + debug("%s: %.3Lf", "rate_deviation", rate_deviation); + + memset(stats_buf, 0, sizeof(stats_buf)); + stats_size = + pv_snprintf(stats_buf, sizeof(stats_buf), "%s = %.3Lf/%.3Lf/%.3Lf/%.3Lf %s\n", + _("rate min/avg/max/mdev"), state->calc.rate_min, rate_mean, state->calc.rate_max, + rate_deviation, state->control.bits ? _("b/s") : _("B/s")); + + if (stats_size > 0 && stats_size < (int) (sizeof(stats_buf))) + pv_tty_write(state, stats_buf, (size_t) stats_size); + } else if (state->control.show_stats && state->calc.measurements_taken < 1) { + char msg_buf[256]; /* flawfinder: ignore */ + int msg_size; + + /* flawfinder: made safe by use of pv_snprintf() */ + + memset(msg_buf, 0, sizeof(msg_buf)); + msg_size = pv_snprintf(msg_buf, sizeof(msg_buf), "%s\n", _("rate not measured")); + + if (msg_size > 0 && msg_size < (int) (sizeof(msg_buf))) + pv_tty_write(state, msg_buf, (size_t) msg_size); + } + return state->status.exit_status; } diff --git a/src/pv/state.c b/src/pv/state.c index 8b67d9f..20fe133 100644 --- a/src/pv/state.c +++ b/src/pv/state.c @@ -85,6 +85,22 @@ pvstate_t pv_state_alloc(const char *program_name) #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; + /* * Get the current working directory, if possible, as a base for * showing relative filenames with --watchfd. @@ -234,6 +250,11 @@ void pv_state_cursor_set(pvstate_t state, bool val) state->control.cursor = val; } +void pv_state_show_stats_set(pvstate_t state, bool val) +{ + state->control.show_stats = val; +} + void pv_state_numeric_set(pvstate_t state, bool val) { state->control.numeric = val;