27 Commits
Author SHA1 Message Date
Andrew Wood f1f333dc7a Update version to 1.8.14. 2024-09-07 21:33:24 +01:00
Andrew Wood 69a56ced7a Correct double-free on exit when using --watchfd - issue #96. 2024-09-07 21:04:09 +01:00
Andrew Wood 2c468b0bb2 Version bump for new release. 2024-08-18 21:59:32 +01:00
Andrew Wood c67248ffc7 Update to add the new strings in the options parser. 2024-08-06 23:35:55 +01:00
Andrew Wood 60936080da Move the "--size @FILE" file size reading into its own function for clarity; standardise its error message format to "program: file: message: detail"; uniquely name variables; refuse to accept a directory as a file; and with this option, try reading the size of a block device from sysfs if we can, to avoid requiring read permissions on the device. 2024-08-06 23:17:15 +01:00
Andrew Wood 4db04564a9 Merge pull request 'Support block devices in @-syntax' (#94) from alexanderperlis/pv:support-block-device-size into main
Reviewed-on: https://codeberg.org/a-j-wood/pv/pulls/94
2024-08-06 20:26:43 +00:00
Alexander Perlis f6b0ddc0b3 Support block devices in @-syntax 2024-08-01 00:36:02 +00:00
Andrew Wood b42399e9a9 Timestamp update. 2024-07-18 22:23:48 +01:00
Andrew Wood ba72056bf2 Version bump. 2024-07-18 22:10:57 +01:00
Andrew Wood b8e4a51228 Update line numbers. 2024-07-18 22:08:34 +01:00
Andrew Wood 0b12f7db42 Update TODO to reflect issue tracker. 2024-07-18 22:01:36 +01:00
Andrew Wood 5053cffdad Further clarification of #92, #93. 2024-07-17 07:45:13 +01:00
Andrew Wood 02f852604f Add #93. 2024-07-17 07:42:18 +01:00
Andrew Wood e4ab8c56a0 Minor adjustment to comments. 2024-07-17 07:41:48 +01:00
Andrew Wood 86016d41d7 Merge pull request 'Improve description and comments for blocking-write() after select()' (#93) from eborisch/pv:update-block-after-select into main
Reviewed-on: https://codeberg.org/a-j-wood/pv/pulls/93
2024-07-17 06:36:50 +00:00
Eric A. Borisch 3fdfd07443 Improve description and comments for blocking-write() after select() 2024-07-16 23:39:15 -05:00
Andrew Wood d801cdd722 Remove spurious strerror() call from debug report. 2024-07-16 22:44:10 +01:00
Andrew Wood 72e5078ce9 Move the MAKE_OUTPUT_NONBLOCKING code to state.c, as it can no longer work in main.c due to accessing internal structures; but still leave it switched off by default for now. 2024-07-16 22:41:31 +01:00
Andrew Wood a7c3f3dd35 Write the error from write() to the debugging output if nwritten is <0. 2024-07-16 22:23:51 +01:00
Andrew Wood 729fc10674 News item and acknowledgement for zero write bug fix (#92). 2024-07-16 22:03:56 +01:00
Andrew Wood 12f0312b00 Move the "stop at size" option setting to before the size calculation, otherwise if the size calculation tries to override that setting, it cannot do so (#91). 2024-07-16 21:58:47 +01:00
Andrew Wood 8c0e3e9dad When checking how many bytes were written, place the constant to the left of the equality check to match the rest of the code (this avoids accidental assignment if one equals sign is accidentally written instead of two), and write the appropriate debug message depending on whether the write was interrupted or it was empty. 2024-07-16 21:54:13 +01:00
Andrew Wood c7104f0c0d Merge pull request 'src/pv/transfer.c: timer going off returns with total_written==0; which is not an error.' (#92) from eborisch/pv:write-can-return-0 into main
Reviewed-on: https://codeberg.org/a-j-wood/pv/pulls/92
2024-07-16 20:47:32 +00:00
Andrew Wood 679638beb2 More details. 2024-07-16 21:42:23 +01:00
Andrew Wood f8fc5844b1 Re-order the output file descriptor setting and the size detection to correct the problem with output block device size detection that was broken in 1.8.10 (#91). 2024-07-16 21:39:29 +01:00
eborisch d86d8cf65a Clarify state. 2024-07-16 03:57:11 +00:00
eborisch 11e5b5fe95 src/pv/transfer.c: write(2) returning 0 is not an error
This is being hit easily on FreeBSD with pv sitting in a zfs send/recv pipeline. As write(2) returning 0 is not an error, handle it similar to returning -1 with EINTR or EAGAIN: wait a bit and try again.
2024-07-15 21:36:57 +00:00
15 changed files with 567 additions and 295 deletions
+2 -1
View File
@@ -4,7 +4,7 @@ dnl Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2024 Andrew Wood
dnl
dnl License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
AC_INIT([pv], [1.8.10], [pv@ivarch.com], [pv], [https://www.ivarch.com/programs/pv.shtml])
AC_INIT([pv], [1.8.14], [pv@ivarch.com], [pv], [https://www.ivarch.com/programs/pv.shtml])
AC_CONFIG_SRCDIR([src/include/config.h.in])
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_HEADERS([src/include/config.h])
@@ -37,6 +37,7 @@ AC_CHECK_HEADERS([termios.h])
AC_CHECK_HEADERS([libgen.h])
AC_CHECK_HEADERS([sys/ioctl.h])
AC_CHECK_HEADERS([libintl.h locale.h])
AC_CHECK_HEADERS([sys/sysmacros.h])
AC_CHECK_MEMBERS([struct stat.st_blksize])
dnl Libraries that may contain key functions.
+4
View File
@@ -92,5 +92,9 @@ is acknowledged and greatly appreciated:
* [Thomas Bertels](https://codeberg.org/tbertels) - updated French translations ([#83](https://codeberg.org/a-j-wood/pv/pulls/83))
* [kevinruddy](https://codeberg.org/kevinruddy) - added decimal units option ([#85](https://codeberg.org/a-j-wood/pv/pulls/85))
* [xmort](https://codeberg.org/xmort) - added "`--output`" option ([#90](https://codeberg.org/a-j-wood/pv/pulls/90))
* [bogiord](https://codeberg.org/bogiord) - reported the loss of output block device size detection in 1.8.10, and suggested the fix ([#91](https://codeberg.org/a-j-wood/pv/issues/91))
* [eborisch](https://codeberg.org/eborisch) - provided fix for misbehaviour when used with "`zfs send`" due to treating zero sized writes (generally due to timer interruption) as end of file ([#92](https://codeberg.org/a-j-wood/pv/pulls/92), [#93](https://codeberg.org/a-j-wood/pv/pulls/93))
* [alexanderperlis](https://codeberg.org/alexanderperlis) - provided initial support for block devices with "`--size @FILE`" ([#94](https://codeberg.org/a-j-wood/pv/pulls/94))
* [jettero](https://codeberg.org/jettero) - reported double-free coredump when using "`--watchfd`" after 1.8.10 ([#96](https://codeberg.org/a-j-wood/pv/issues/96))
---
+13
View File
@@ -1,3 +1,16 @@
### 1.8.14 - 7 September 2024
* fix: correct double-free on exit when using "`--watchfd`" ([#96](https://codeberg.org/a-j-wood/pv/issues/96)) reported by [jettero](https://codeberg.org/jettero)
### 1.8.13 - 18 August 2024
* feature: when using "`--size @FILE`", _FILE_ can be a block device, and its size will be used (pull request [#94](https://codeberg.org/a-j-wood/pv/pulls/94)) supplied by [alexanderperlis](https://codeberg.org/alexanderperlis)
### 1.8.12 - 18 July 2024
* fix: correct the detection of output block device size that was broken in 1.8.10 ([#91](https://codeberg.org/a-j-wood/pv/issues/91))
* fix: do not treat a zero/interrupted write as an end of file (pull requests [#92](https://codeberg.org/a-j-wood/pv/pulls/92) and [#93](https://codeberg.org/a-j-wood/pv/pulls/93))
### 1.8.10 - 15 June 2024
* feature: new "`--output`" option to write to a file instead of standard output (pull request [#90](https://codeberg.org/a-j-wood/pv/pulls/90)) supplied by [xmort](https://codeberg.org/xmort)
+6 -2
View File
@@ -20,10 +20,14 @@ Things still to do. (#n) indicates the issue tracker number.
* ([#48](https://codeberg.org/a-j-wood/pv/issues/48)) Option to show multiple files with individual sizes and a cumulative total (Zach Riggle - Jul 2021)
* ([#49](https://codeberg.org/a-j-wood/pv/issues/49)) Option to provide stats for avg/min/max/stddev throughput (Venky.N.Iyer)
* ([#50](https://codeberg.org/a-j-wood/pv/issues/50)) Allow pv to report on a whole pipeline at once (Will Entriken - Feb 2011)
* ([#52](https://codeberg.org/a-j-wood/pv/issues/52)) Strange race condition that affects --wait when writing to GnuPG ([danielyli](https://github.com/danielyli))
* ([#54](https://codeberg.org/a-j-wood/pv/issues/54)) Run command every n percent ([haarp](https://github.com/haarp))
* ([#56](https://codeberg.org/a-j-wood/pv/issues/56)) Support for backgrounding pv, and allowing it to be monitored separately ([jimbobmcgee](https://github.com/jimbobmcgee))
* ([#59](https://codeberg.org/a-j-wood/pv/issues/59)) Slow transfer under termux but faster if strace is used ([lateautumn233](https://github.com/lateautumn233))
* ([#67](https://codeberg.org/a-j-wood/pv/issues/67)) Wrap another process to monitor its stdin & stdout ([Alex Mason](https://github.com/axman6))
* ([#76](https://codeberg.org/a-j-wood/pv/issues/76)) Provide a way to test translations without installing
* ([#81](https://codeberg.org/a-j-wood/pv/issues/81)) Keep last output on terminal when "pv -d" is done
* ([#81](https://codeberg.org/a-j-wood/pv/issues/81)) Keep last output on terminal when "`pv -d`" is done ([KimHansen](https://codeberg.org/KimHansen))
* ([#84](https://codeberg.org/a-j-wood/pv/issues/84)) Allow using "`--size`" with "`--watchfd`" to show total progress of a process ([tbertels](https://codeberg.org/tbertels))
* ([#87](https://codeberg.org/a-j-wood/pv/issues/87)) Inconsistent buffer filling when writes are stuck, particularly on Cygwin ([basinilya](https://codeberg.org/basinilya))
* ([#89](https://codeberg.org/a-j-wood/pv/issues/89)) Intermittent terminal settings reset failures after multi PV pipeline completes ([stdedos](https://codeberg.org/stdedos))
Any assistance would be appreciated.
+1 -1
View File
@@ -1,4 +1,4 @@
.TH PV 1 "June 2024" Linux "User Manuals"
.TH PV 1 "September 2024" Linux "User Manuals"
.SH NAME
pv \- monitor the progress of data through a pipe
.SH SYNOPSIS
+68 -48
View File
@@ -1,7 +1,7 @@
msgid ""
msgstr ""
"Report-Msgid-Bugs-To: pv@ivarch.com\n"
"POT-Creation-Date: 2024-06-15 23:26+0100\n"
"POT-Creation-Date: 2024-08-18 22:01+0100\n"
"Language: de\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Date: 1999-06-01 15:18:29+0100\n"
@@ -254,49 +254,69 @@ msgstr ""
msgid "Please report any bugs to: %s"
msgstr "Bitte senden Sie Fehlerberichte an %s"
#: src/main/main.c:74
#: src/main/main.c:71
msgid "state allocation failed"
msgstr "Zustandszuweisung fehlgeschlagen"
#: src/main/options.c:177
msgid "option structure allocation failed"
msgstr "`option' konnte nicht allokiert werden"
#: src/main/options.c:196
msgid "option structure argv allocation failed"
msgstr "`option' (argv) konnte nicht allokiert werden"
#: src/main/options.c:258
msgid "integer argument expected"
msgstr "Ganzzahliges Argument erwartet"
#: src/main/options.c:269
msgid "numeric argument expected"
msgstr "numerisches Argument erwartet"
#: src/main/options.c:280
msgid "process ID or pid:fd pair expected"
msgstr "Prozess-ID oder PID:FD-Paar erwartet"
#: src/main/options.c:287
msgid "invalid process ID"
msgstr "ungültige Prozess-ID"
#: src/main/options.c:391 src/pv/file.c:324
#: src/main/options.c:138 src/pv/file.c:324
msgid "failed to stat file"
msgstr "Dateiinformationen konnten nicht gelesen werden"
#: src/main/options.c:502
#: src/main/options.c:152
msgid "is a directory"
msgstr ""
#: src/main/options.c:181
msgid "failed to generate sysfs filename"
msgstr ""
#: src/main/options.c:203
msgid "failed to read sysfs size file"
msgstr ""
#: src/main/options.c:223
msgid "failed to open block device"
msgstr ""
#: src/main/options.c:233
msgid "failed to determine size of block device"
msgstr ""
#: src/main/options.c:334
msgid "option structure allocation failed"
msgstr "`option' konnte nicht allokiert werden"
#: src/main/options.c:353
msgid "option structure argv allocation failed"
msgstr "`option' (argv) konnte nicht allokiert werden"
#: src/main/options.c:415
msgid "integer argument expected"
msgstr "Ganzzahliges Argument erwartet"
#: src/main/options.c:426
msgid "numeric argument expected"
msgstr "numerisches Argument erwartet"
#: src/main/options.c:437
msgid "process ID or pid:fd pair expected"
msgstr "Prozess-ID oder PID:FD-Paar erwartet"
#: src/main/options.c:444
msgid "invalid process ID"
msgstr "ungültige Prozess-ID"
#: src/main/options.c:647
#, c-format
msgid "Try `%s --help' for more information."
msgstr "`%s --help' zeigt weitere Informationen an."
#: src/main/options.c:504
#: src/main/options.c:649
#, c-format
msgid "Try `%s -h' for more information."
msgstr "`%s -h' zeigt weitere Informationen an."
#: src/main/options.c:535
#: src/main/options.c:680
msgid ""
"cannot use line mode or transfer modifier options when watching file "
"descriptors"
@@ -304,23 +324,23 @@ msgstr ""
"Beim Anzeigen von Dateideskriptoren können keine Optionen für den "
"Zeilenmodus oder den Übertragungsmodifikator verwendet werden"
#: src/main/options.c:544
#: src/main/options.c:689
msgid "cannot use cursor positioning when watching file descriptors"
msgstr ""
"Beim Anzeigen von Dateideskriptoren können keine Zeilenmodus- oder "
"Übertragungsmodifikatoroptionen verwendet werden."
#: src/main/options.c:553
#: src/main/options.c:698
msgid "cannot use remote control when watching file descriptors"
msgstr ""
"kann keine Fernbedienung verwenden, wenn Dateideskriptoren angezeigt werden"
#: src/main/options.c:562
#: src/main/options.c:707
msgid "cannot transfer files when watching file descriptors"
msgstr ""
"Dateien können beim Betrachten von Dateideskriptoren nicht übertragen werden"
#: src/main/options.c:577
#: src/main/options.c:722
msgid "not available on systems without /proc/self/fdinfo"
msgstr "Nicht verfügbar auf Systemen ohne /proc/self/fdinfo"
@@ -372,7 +392,7 @@ msgstr ""
msgid "yzafpnum KMGTPEZY"
msgstr ""
#: src/pv/display.c:750 src/pv/transfer.c:961
#: src/pv/display.c:750 src/pv/transfer.c:970
msgid "buffer allocation failed"
msgstr "Puffer konnte nicht allokiert werden"
@@ -380,7 +400,7 @@ msgstr "Puffer konnte nicht allokiert werden"
msgid "b"
msgstr ""
#: src/pv/display.c:859 src/pv/transfer.c:596
#: src/pv/display.c:859 src/pv/transfer.c:602
msgid "B"
msgstr "B"
@@ -436,51 +456,51 @@ msgstr ""
msgid "pid"
msgstr ""
#: src/pv/state.c:36
#: src/pv/state.c:40
msgid "history structure allocation failed"
msgstr ""
#: src/pv/state.c:431 src/pv/state.c:442
#: src/pv/state.c:444 src/pv/state.c:455
msgid "file list allocation failed"
msgstr ""
#: src/pv/transfer.c:458
#: src/pv/transfer.c:464
msgid "read failed"
msgstr "read-Aufruf fehlgeschlagen"
#: src/pv/transfer.c:481
#: src/pv/transfer.c:487
msgid "warning: read errors detected"
msgstr "warnung: lesefehler erkannt"
#: src/pv/transfer.c:497
#: src/pv/transfer.c:503
msgid "file is not seekable"
msgstr "datei ist nicht durchsuchbar"
#: src/pv/transfer.c:575
#: src/pv/transfer.c:581
msgid "failed to seek past error"
msgstr "konnte den Fehler nicht überwinden"
#: src/pv/transfer.c:595
#: src/pv/transfer.c:601
msgid "skipped past read error"
msgstr "über den Lesefehler hinaus verschoben"
#: src/pv/transfer.c:635
#: src/pv/transfer.c:641
msgid "no transfer buffer allocated"
msgstr ""
#: src/pv/transfer.c:676
#: src/pv/transfer.c:682
msgid "failed to set interval timer"
msgstr ""
#: src/pv/transfer.c:697
#: src/pv/transfer.c:707
msgid "failed to clear interval timer"
msgstr ""
#: src/pv/transfer.c:822
#: src/pv/transfer.c:831
msgid "write failed"
msgstr "write-Aufruf fehlgeschlagen"
#: src/pv/transfer.c:1059
#: src/pv/transfer.c:1068
msgid "select call failed"
msgstr "select-Aufruf fehlgeschlagen"
+68 -48
View File
@@ -1,7 +1,7 @@
msgid ""
msgstr ""
"Report-Msgid-Bugs-To: pv@ivarch.com\n"
"POT-Creation-Date: 2024-06-15 23:26+0100\n"
"POT-Creation-Date: 2024-08-18 22:01+0100\n"
"Language: fr\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Date: 1999-06-01 15:18:29+0100\n"
@@ -255,49 +255,69 @@ msgstr ""
msgid "Please report any bugs to: %s"
msgstr "SVP rapporter tous bogues à %s"
#: src/main/main.c:74
#: src/main/main.c:71
msgid "state allocation failed"
msgstr "échec de l'allocation de mémoire de condition"
#: src/main/options.c:177
msgid "option structure allocation failed"
msgstr "l'allocation pour la structure d'une option a échoué"
#: src/main/options.c:196
msgid "option structure argv allocation failed"
msgstr "l'allocation pour la structure de l'option argv a échoué"
#: src/main/options.c:258
msgid "integer argument expected"
msgstr "Valeur entière attendue"
#: src/main/options.c:269
msgid "numeric argument expected"
msgstr "Valeur numérique attendue"
#: src/main/options.c:280
msgid "process ID or pid:fd pair expected"
msgstr "ID de processus ou paire pid:fd attendue"
#: src/main/options.c:287
msgid "invalid process ID"
msgstr "ID de processus non valide"
#: src/main/options.c:391 src/pv/file.c:324
#: src/main/options.c:138 src/pv/file.c:324
msgid "failed to stat file"
msgstr "échec à statuer sur le fichier"
#: src/main/options.c:502
#: src/main/options.c:152
msgid "is a directory"
msgstr ""
#: src/main/options.c:181
msgid "failed to generate sysfs filename"
msgstr ""
#: src/main/options.c:203
msgid "failed to read sysfs size file"
msgstr ""
#: src/main/options.c:223
msgid "failed to open block device"
msgstr ""
#: src/main/options.c:233
msgid "failed to determine size of block device"
msgstr ""
#: src/main/options.c:334
msgid "option structure allocation failed"
msgstr "l'allocation pour la structure d'une option a échoué"
#: src/main/options.c:353
msgid "option structure argv allocation failed"
msgstr "l'allocation pour la structure de l'option argv a échoué"
#: src/main/options.c:415
msgid "integer argument expected"
msgstr "Valeur entière attendue"
#: src/main/options.c:426
msgid "numeric argument expected"
msgstr "Valeur numérique attendue"
#: src/main/options.c:437
msgid "process ID or pid:fd pair expected"
msgstr "ID de processus ou paire pid:fd attendue"
#: src/main/options.c:444
msgid "invalid process ID"
msgstr "ID de processus non valide"
#: src/main/options.c:647
#, c-format
msgid "Try `%s --help' for more information."
msgstr "Essayez `%s --help' pour plus d'informations."
#: src/main/options.c:504
#: src/main/options.c:649
#, c-format
msgid "Try `%s -h' for more information."
msgstr "Essayez `%s -h' pour plus d'informations."
#: src/main/options.c:535
#: src/main/options.c:680
msgid ""
"cannot use line mode or transfer modifier options when watching file "
"descriptors"
@@ -305,25 +325,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:544
#: src/main/options.c:689
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:553
#: src/main/options.c:698
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:562
#: src/main/options.c:707
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:577
#: src/main/options.c:722
msgid "not available on systems without /proc/self/fdinfo"
msgstr "non disponible sur les systèmes sans /proc/self/fdinfo"
@@ -377,7 +397,7 @@ msgstr ""
msgid "yzafpnum KMGTPEZY"
msgstr ""
#: src/pv/display.c:750 src/pv/transfer.c:961
#: src/pv/display.c:750 src/pv/transfer.c:970
msgid "buffer allocation failed"
msgstr "échec de l'allocation de mémoire tampon"
@@ -385,7 +405,7 @@ msgstr "échec de l'allocation de mémoire tampon"
msgid "b"
msgstr ""
#: src/pv/display.c:859 src/pv/transfer.c:596
#: src/pv/display.c:859 src/pv/transfer.c:602
msgid "B"
msgstr "O"
@@ -441,51 +461,51 @@ msgstr ""
msgid "pid"
msgstr ""
#: src/pv/state.c:36
#: src/pv/state.c:40
msgid "history structure allocation failed"
msgstr "l'allocation de la structure de l'historique a échoué"
#: src/pv/state.c:431 src/pv/state.c:442
#: src/pv/state.c:444 src/pv/state.c:455
msgid "file list allocation failed"
msgstr "échec de l'allocation de la liste de fichiers"
#: src/pv/transfer.c:458
#: src/pv/transfer.c:464
msgid "read failed"
msgstr "la lecture a échoué"
#: src/pv/transfer.c:481
#: src/pv/transfer.c:487
msgid "warning: read errors detected"
msgstr "avertissement : erreurs de lecture détectées"
#: src/pv/transfer.c:497
#: src/pv/transfer.c:503
msgid "file is not seekable"
msgstr "ne peut pas se déplacer dans le fichier"
#: src/pv/transfer.c:575
#: src/pv/transfer.c:581
msgid "failed to seek past error"
msgstr "n'a pas réussi à dépasser l'erreur"
#: src/pv/transfer.c:595
#: src/pv/transfer.c:601
msgid "skipped past read error"
msgstr "erreur de lecture dépassée"
#: src/pv/transfer.c:635
#: src/pv/transfer.c:641
msgid "no transfer buffer allocated"
msgstr "aucun tampon de transfert alloué"
#: src/pv/transfer.c:676
#: src/pv/transfer.c:682
msgid "failed to set interval timer"
msgstr ""
#: src/pv/transfer.c:697
#: src/pv/transfer.c:707
msgid "failed to clear interval timer"
msgstr ""
#: src/pv/transfer.c:822
#: src/pv/transfer.c:831
msgid "write failed"
msgstr "l'écriture a échoué"
#: src/pv/transfer.c:1059
#: src/pv/transfer.c:1068
msgid "select call failed"
msgstr "l'appel de sélection a échoué"
+68 -48
View File
@@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: pv@ivarch.com\n"
"POT-Creation-Date: 2024-06-15 23:26+0100\n"
"POT-Creation-Date: 2024-08-18 22:01+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"
@@ -248,67 +248,87 @@ msgstr ""
msgid "Please report any bugs to: %s"
msgstr "Proszę przesyłać zgłoszenia błędów do %s"
#: src/main/main.c:74
#: src/main/main.c:71
msgid "state allocation failed"
msgstr ""
#: src/main/options.c:177
msgid "option structure allocation failed"
msgstr "nie udało się zaalokować struktur opcji"
#: src/main/options.c:196
msgid "option structure argv allocation failed"
msgstr "nie udało się zaalokować struktur opcji argv"
#: src/main/options.c:258
msgid "integer argument expected"
msgstr ""
#: src/main/options.c:269
msgid "numeric argument expected"
msgstr ""
#: src/main/options.c:280
msgid "process ID or pid:fd pair expected"
msgstr ""
#: src/main/options.c:287
msgid "invalid process ID"
msgstr ""
#: src/main/options.c:391 src/pv/file.c:324
#: src/main/options.c:138 src/pv/file.c:324
msgid "failed to stat file"
msgstr "nie udało się wykonać operacji stat na pliku"
#: src/main/options.c:502
#: src/main/options.c:152
msgid "is a directory"
msgstr ""
#: src/main/options.c:181
msgid "failed to generate sysfs filename"
msgstr ""
#: src/main/options.c:203
msgid "failed to read sysfs size file"
msgstr ""
#: src/main/options.c:223
msgid "failed to open block device"
msgstr ""
#: src/main/options.c:233
msgid "failed to determine size of block device"
msgstr ""
#: src/main/options.c:334
msgid "option structure allocation failed"
msgstr "nie udało się zaalokować struktur opcji"
#: src/main/options.c:353
msgid "option structure argv allocation failed"
msgstr "nie udało się zaalokować struktur opcji argv"
#: src/main/options.c:415
msgid "integer argument expected"
msgstr ""
#: src/main/options.c:426
msgid "numeric argument expected"
msgstr ""
#: src/main/options.c:437
msgid "process ID or pid:fd pair expected"
msgstr ""
#: src/main/options.c:444
msgid "invalid process ID"
msgstr ""
#: src/main/options.c:647
#, c-format
msgid "Try `%s --help' for more information."
msgstr "Spróbuj `%s --help' by uzyskać więcej informacji"
#: src/main/options.c:504
#: src/main/options.c:649
#, c-format
msgid "Try `%s -h' for more information."
msgstr "Spróbuj `%s -h' by uzyskać więcej informacji"
#: src/main/options.c:535
#: src/main/options.c:680
msgid ""
"cannot use line mode or transfer modifier options when watching file "
"descriptors"
msgstr ""
#: src/main/options.c:544
#: src/main/options.c:689
msgid "cannot use cursor positioning when watching file descriptors"
msgstr ""
#: src/main/options.c:553
#: src/main/options.c:698
msgid "cannot use remote control when watching file descriptors"
msgstr ""
#: src/main/options.c:562
#: src/main/options.c:707
msgid "cannot transfer files when watching file descriptors"
msgstr ""
#: src/main/options.c:577
#: src/main/options.c:722
msgid "not available on systems without /proc/self/fdinfo"
msgstr ""
@@ -361,7 +381,7 @@ msgstr ""
msgid "yzafpnum KMGTPEZY"
msgstr ""
#: src/pv/display.c:750 src/pv/transfer.c:961
#: src/pv/display.c:750 src/pv/transfer.c:970
msgid "buffer allocation failed"
msgstr "nie udało się zaalokować bufora"
@@ -369,7 +389,7 @@ msgstr "nie udało się zaalokować bufora"
msgid "b"
msgstr ""
#: src/pv/display.c:859 src/pv/transfer.c:596
#: src/pv/display.c:859 src/pv/transfer.c:602
msgid "B"
msgstr "B"
@@ -426,52 +446,52 @@ msgstr ""
msgid "pid"
msgstr ""
#: src/pv/state.c:36
#: src/pv/state.c:40
msgid "history structure allocation failed"
msgstr ""
#: src/pv/state.c:431 src/pv/state.c:442
#: src/pv/state.c:444 src/pv/state.c:455
msgid "file list allocation failed"
msgstr ""
#: src/pv/transfer.c:458
#: src/pv/transfer.c:464
msgid "read failed"
msgstr "błąd odczytu"
#: src/pv/transfer.c:481
#: src/pv/transfer.c:487
msgid "warning: read errors detected"
msgstr ""
#: src/pv/transfer.c:497
#: src/pv/transfer.c:503
msgid "file is not seekable"
msgstr ""
#: src/pv/transfer.c:575
#: src/pv/transfer.c:581
msgid "failed to seek past error"
msgstr ""
#: src/pv/transfer.c:595
#: src/pv/transfer.c:601
msgid "skipped past read error"
msgstr ""
#: src/pv/transfer.c:635
#: src/pv/transfer.c:641
msgid "no transfer buffer allocated"
msgstr ""
#: src/pv/transfer.c:676
#: src/pv/transfer.c:682
msgid "failed to set interval timer"
msgstr ""
# "Przewidywany czas ukończenia" for ETA is too long
#: src/pv/transfer.c:697
#: src/pv/transfer.c:707
msgid "failed to clear interval timer"
msgstr ""
#: src/pv/transfer.c:822
#: src/pv/transfer.c:831
msgid "write failed"
msgstr "błąd zapisu"
#: src/pv/transfer.c:1059
#: src/pv/transfer.c:1068
msgid "select call failed"
msgstr "nie udało się wywołać funkcji select"
+68 -48
View File
@@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: pv@ivarch.com\n"
"POT-Creation-Date: 2024-06-15 23:26+0100\n"
"POT-Creation-Date: 2024-08-18 22:01+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"
@@ -248,49 +248,69 @@ msgstr ""
msgid "Please report any bugs to: %s"
msgstr "Por favor, reporte quaisquer defeitos para %s"
#: src/main/main.c:74
#: src/main/main.c:71
msgid "state allocation failed"
msgstr "alocação de memória de status falhou"
#: src/main/options.c:177
msgid "option structure allocation failed"
msgstr "erro na alocação da estrutura de opções"
#: src/main/options.c:196
msgid "option structure argv allocation failed"
msgstr "erro na alocação da estrutura de opções argv"
#: src/main/options.c:258
msgid "integer argument expected"
msgstr "argumento inteiro esperado"
#: src/main/options.c:269
msgid "numeric argument expected"
msgstr "argumento numérico esperado"
#: src/main/options.c:280
msgid "process ID or pid:fd pair expected"
msgstr "ID do processo ou par pid:fd esperado"
#: src/main/options.c:287
msgid "invalid process ID"
msgstr "ID de processo inválido"
#: src/main/options.c:391 src/pv/file.c:324
#: src/main/options.c:138 src/pv/file.c:324
msgid "failed to stat file"
msgstr "erro obtendo informações do arquivo"
#: src/main/options.c:502
#: src/main/options.c:152
msgid "is a directory"
msgstr ""
#: src/main/options.c:181
msgid "failed to generate sysfs filename"
msgstr ""
#: src/main/options.c:203
msgid "failed to read sysfs size file"
msgstr ""
#: src/main/options.c:223
msgid "failed to open block device"
msgstr ""
#: src/main/options.c:233
msgid "failed to determine size of block device"
msgstr ""
#: src/main/options.c:334
msgid "option structure allocation failed"
msgstr "erro na alocação da estrutura de opções"
#: src/main/options.c:353
msgid "option structure argv allocation failed"
msgstr "erro na alocação da estrutura de opções argv"
#: src/main/options.c:415
msgid "integer argument expected"
msgstr "argumento inteiro esperado"
#: src/main/options.c:426
msgid "numeric argument expected"
msgstr "argumento numérico esperado"
#: src/main/options.c:437
msgid "process ID or pid:fd pair expected"
msgstr "ID do processo ou par pid:fd esperado"
#: src/main/options.c:444
msgid "invalid process ID"
msgstr "ID de processo inválido"
#: src/main/options.c:647
#, c-format
msgid "Try `%s --help' for more information."
msgstr "Tente `%s --help' para maiores informações."
#: src/main/options.c:504
#: src/main/options.c:649
#, c-format
msgid "Try `%s -h' for more information."
msgstr "Tente `%s -h' para maiores informações."
#: src/main/options.c:535
#: src/main/options.c:680
msgid ""
"cannot use line mode or transfer modifier options when watching file "
"descriptors"
@@ -298,21 +318,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:544
#: src/main/options.c:689
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:553
#: src/main/options.c:698
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:562
#: src/main/options.c:707
msgid "cannot transfer files when watching file descriptors"
msgstr "não pode transferir arquivos ao assistir descritores de arquivo"
#: src/main/options.c:577
#: src/main/options.c:722
msgid "not available on systems without /proc/self/fdinfo"
msgstr "não disponível em sistemas sem /proc/self/fdinfo"
@@ -364,7 +384,7 @@ msgstr ""
msgid "yzafpnum KMGTPEZY"
msgstr ""
#: src/pv/display.c:750 src/pv/transfer.c:961
#: src/pv/display.c:750 src/pv/transfer.c:970
msgid "buffer allocation failed"
msgstr "erro alocando o buffer"
@@ -372,7 +392,7 @@ msgstr "erro alocando o buffer"
msgid "b"
msgstr ""
#: src/pv/display.c:859 src/pv/transfer.c:596
#: src/pv/display.c:859 src/pv/transfer.c:602
msgid "B"
msgstr ""
@@ -428,51 +448,51 @@ msgstr ""
msgid "pid"
msgstr ""
#: src/pv/state.c:36
#: src/pv/state.c:40
msgid "history structure allocation failed"
msgstr ""
#: src/pv/state.c:431 src/pv/state.c:442
#: src/pv/state.c:444 src/pv/state.c:455
msgid "file list allocation failed"
msgstr ""
#: src/pv/transfer.c:458
#: src/pv/transfer.c:464
msgid "read failed"
msgstr "erro de leitura"
#: src/pv/transfer.c:481
#: src/pv/transfer.c:487
msgid "warning: read errors detected"
msgstr "aviso: erros de leitura detectados"
#: src/pv/transfer.c:497
#: src/pv/transfer.c:503
msgid "file is not seekable"
msgstr "não pode mover dentro do arquivo"
#: src/pv/transfer.c:575
#: src/pv/transfer.c:581
msgid "failed to seek past error"
msgstr "não pode ir além do erro"
#: src/pv/transfer.c:595
#: src/pv/transfer.c:601
msgid "skipped past read error"
msgstr "ignorado erro de leitura"
#: src/pv/transfer.c:635
#: src/pv/transfer.c:641
msgid "no transfer buffer allocated"
msgstr ""
#: src/pv/transfer.c:676
#: src/pv/transfer.c:682
msgid "failed to set interval timer"
msgstr ""
#: src/pv/transfer.c:697
#: src/pv/transfer.c:707
msgid "failed to clear interval timer"
msgstr ""
#: src/pv/transfer.c:822
#: src/pv/transfer.c:831
msgid "write failed"
msgstr "erro de gravação"
#: src/pv/transfer.c:1059
#: src/pv/transfer.c:1068
msgid "select call failed"
msgstr "erro na chamada da função select"
+3
View File
@@ -169,6 +169,9 @@
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/sysmacros.h> header file. */
#undef HAVE_SYS_SYSMACROS_H
/* Define to 1 if you have the <sys/time.h> header file. */
#undef HAVE_SYS_TIME_H
+67 -68
View File
@@ -11,9 +11,6 @@
#include "options.h"
#include "pv.h"
/* We do not set this because it breaks "dd" - see below. */
/* #undef MAKE_OUTPUT_NONBLOCKING */
#include <stdio.h>
#include <string.h>
#include <errno.h>
@@ -194,27 +191,6 @@ int main(int argc, char **argv)
pv_state_inputfiles(state, opts->argc, (const char **) (opts->argv));
}
/* Total size calculation, in normal transfer mode. */
if (0 == opts->watch_pid) {
/*
* If no size was given, try to calculate the total size.
*/
if (0 == opts->size) {
pv_state_linemode_set(state, opts->linemode);
pv_state_null_terminated_lines_set(state, opts->null_terminated_lines);
opts->size = pv_calc_total_size(state);
debug("%s: %llu", "no size given - calculated", opts->size);
}
/*
* If the size is unknown, we cannot have an ETA.
*/
if (opts->size < 1) {
opts->eta = false;
debug("%s", "size unknown - ETA disabled");
}
}
/*
* If stderr is not a terminal and we're neither forcing output nor
* outputting numerically, we will have nothing to display at all.
@@ -265,43 +241,10 @@ int main(int argc, char **argv)
opts->interval = 600;
/*
* Copy parameters from options into main state.
*/
pv_state_interval_set(state, opts->interval);
pv_state_width_set(state, opts->width, opts->width_set_manually);
pv_state_height_set(state, opts->height, opts->height_set_manually);
pv_state_no_display_set(state, opts->no_display);
pv_state_force_set(state, opts->force);
pv_state_cursor_set(state, opts->cursor);
pv_state_numeric_set(state, opts->numeric);
pv_state_wait_set(state, opts->wait);
pv_state_delay_start_set(state, opts->delay_start);
pv_state_linemode_set(state, opts->linemode);
pv_state_bits_set(state, opts->bits);
pv_state_decimal_units_set(state, opts->decimal_units);
pv_state_null_terminated_lines_set(state, opts->null_terminated_lines);
pv_state_skip_errors_set(state, opts->skip_errors);
pv_state_error_skip_block_set(state, opts->error_skip_block);
pv_state_stop_at_size_set(state, opts->stop_at_size);
pv_state_sync_after_write_set(state, opts->sync_after_write);
pv_state_direct_io_set(state, opts->direct_io);
pv_state_discard_input_set(state, opts->discard_input);
pv_state_rate_limit_set(state, opts->rate_limit);
pv_state_target_buffer_size_set(state, opts->buffer_size);
pv_state_no_splice_set(state, opts->no_splice);
pv_state_size_set(state, opts->size);
pv_state_name_set(state, opts->name);
pv_state_format_string_set(state, opts->format);
pv_state_watch_pid_set(state, opts->watch_pid);
pv_state_watch_fd_set(state, opts->watch_fd);
pv_state_average_rate_window_set(state, opts->average_rate_window);
pv_state_set_format(state, opts->progress, opts->timer, opts->eta,
opts->fineta, opts->rate, opts->average_rate,
opts->bytes, opts->bufpercent, opts->lastwritten, opts->name);
/*
* Set output file, treating no output or "-" as stdout
* Set output file, treating no output or "-" as stdout; we have to
* do this before looking at setting the size, as the size
* calculation looks at the output file if the input size can't be
* calculated (issue #91).
*/
if (NULL == opts->output || 0 == strcmp(opts->output, "-")) {
pv_state_output_set(state, STDOUT_FILENO, "(stdout)");
@@ -323,15 +266,71 @@ int main(int argc, char **argv)
pv_state_output_set(state, fd, opts->output);
}
#ifdef MAKE_OUTPUT_NONBLOCKING
/*
* Try and make the output use non-blocking I/O.
*
* Note that this can cause problems with (broken) applications
* such as dd when used in a pipeline.
* Copy the "stop at size" option before checking the total size,
* since calculating the size from the output block device size
* after this may want to force this setting on, and if we set it
* afterwards, we undo the override.
*/
fcntl(state->control.output_fd, F_SETFL, O_NONBLOCK | fcntl(state->control.output_fd, F_GETFL));
#endif /* MAKE_OUTPUT_NONBLOCKING */
pv_state_stop_at_size_set(state, opts->stop_at_size);
/* Total size calculation, in normal transfer mode. */
if (0 == opts->watch_pid) {
/*
* If no size was given, try to calculate the total size.
*/
if (0 == opts->size) {
pv_state_linemode_set(state, opts->linemode);
pv_state_null_terminated_lines_set(state, opts->null_terminated_lines);
opts->size = pv_calc_total_size(state);
debug("%s: %llu", "no size given - calculated", opts->size);
}
/*
* If the size is unknown, we cannot have an ETA.
*/
if (opts->size < 1) {
opts->eta = false;
debug("%s", "size unknown - ETA disabled");
}
}
/*
* Copy the remaining parameters from the options into the main
* state.
*/
pv_state_interval_set(state, opts->interval);
pv_state_width_set(state, opts->width, opts->width_set_manually);
pv_state_height_set(state, opts->height, opts->height_set_manually);
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_numeric_set(state, opts->numeric);
pv_state_wait_set(state, opts->wait);
pv_state_delay_start_set(state, opts->delay_start);
pv_state_linemode_set(state, opts->linemode);
pv_state_bits_set(state, opts->bits);
pv_state_decimal_units_set(state, opts->decimal_units);
pv_state_null_terminated_lines_set(state, opts->null_terminated_lines);
pv_state_skip_errors_set(state, opts->skip_errors);
pv_state_error_skip_block_set(state, opts->error_skip_block);
pv_state_sync_after_write_set(state, opts->sync_after_write);
pv_state_direct_io_set(state, opts->direct_io);
pv_state_discard_input_set(state, opts->discard_input);
pv_state_rate_limit_set(state, opts->rate_limit);
pv_state_target_buffer_size_set(state, opts->buffer_size);
pv_state_no_splice_set(state, opts->no_splice);
pv_state_size_set(state, opts->size);
pv_state_name_set(state, opts->name);
pv_state_format_string_set(state, opts->format);
pv_state_watch_pid_set(state, opts->watch_pid);
pv_state_watch_fd_set(state, opts->watch_fd);
pv_state_average_rate_window_set(state, opts->average_rate_window);
pv_state_set_format(state, opts->progress, opts->timer, opts->eta,
opts->fineta, opts->rate, opts->average_rate,
opts->bytes, opts->bufpercent, opts->lastwritten, opts->name);
/* Initialise the signal handling. */
pv_sig_init(state);
+163 -18
View File
@@ -15,6 +15,15 @@
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
#ifdef HAVE_SYS_SYSMACROS_H
#include <sys/sysmacros.h>
#ifdef major
#ifdef minor
#define CAN_BUILD_SYSFS_FILENAME 1
#endif
#endif
#endif
#include <fcntl.h>
#include <unistd.h>
#ifdef HAVE_GETOPT_H
#include <getopt.h>
@@ -88,6 +97,154 @@ bool opts_add_file(opts_t opts, const char *filename)
}
/*
* Set opts->size from the size of the file whose name is size_file,
* returning false (and reporting the error) if there is a problem.
*
* If size_file points to a block device, the size of the block device is
* used.
*/
static bool opts_use_size_of_file(opts_t opts, const char *size_file)
{
struct stat sb;
int stat_rc;
#ifdef CAN_BUILD_SYSFS_FILENAME
char sysfs_filename[512]; /* flawfinder: ignore */
FILE *sysfs_fptr;
long long sysfs_size;
#endif /* CAN_BUILD_SYSFS_FILENAME */
int device_fd;
off_t device_size;
/*
* flawfinder rationale: sysfs_filename is only used with
* pv_snprintf() which guarantees it will be bounded and zero
* terminated.
*/
stat_rc = 0;
memset(&sb, 0, sizeof(sb));
stat_rc = stat(size_file, &sb);
if (0 != stat_rc) {
/*@-mustfreefresh@ */
/*
* splint note: the gettext calls made by _() cause memory
* leak warnings, but in this case it's unavoidable, and
* mitigated by the fact we only translate each string once.
*/
fprintf(stderr, "%s: %s: %s: %s\n",
opts->program_name, size_file, _("failed to stat file"), strerror(errno));
return false;
/*@+mustfreefresh@ */
}
/* This was a regular file - use its size and return. */
if (S_ISREG((mode_t) (sb.st_mode))) {
opts->size = (off_t) (sb.st_size);
return true;
}
/* This was a directory - report an error. */
if (S_ISDIR((mode_t) (sb.st_mode))) {
/*@-mustfreefresh@ *//* see above */
fprintf(stderr, "%s: %s: %s\n", opts->program_name, size_file, _("is a directory"));
return false;
/*@+mustfreefresh@ */
}
/* This was not a block device - just use the size and return. */
if (!S_ISBLK((mode_t) (sb.st_mode))) {
opts->size = (off_t) (sb.st_size);
return true;
}
/*
* Block device - determine its size by looking for
* /sys/dev/block/MAJOR:MINOR/size, and if that fails, try opening
* the file and seeking to the end.
*/
#ifdef CAN_BUILD_SYSFS_FILENAME
/*
* Try the sysfs method - lightest touch and requires no read access
* to the actual block device.
*/
memset(sysfs_filename, 0, sizeof(sysfs_filename));
if (pv_snprintf
(sysfs_filename, sizeof(sysfs_filename), "/sys/dev/block/%u:%u/size", major(sb.st_rdev),
minor(sb.st_rdev)) < 0) {
/*@-mustfreefresh@ *//* see above */
fprintf(stderr, "%s: %s: %s: %s\n",
opts->program_name, size_file, _("failed to generate sysfs filename"), strerror(errno));
return false;
/*@+mustfreefresh@ */
}
sysfs_fptr = fopen(sysfs_filename, "r"); /* flawfinder: ignore */
/*
* flawfinder rationale: sysfs is trusted here, the filename is
* predictable, and we are restricted to reading one number.
*/
if (NULL != sysfs_fptr) {
sysfs_size = -1;
if (1 == fscanf(sysfs_fptr, "%lld", &sysfs_size)) {
/* Read successful - use the value (* 512) and return. */
(void) fclose(sysfs_fptr);
opts->size = (off_t) sysfs_size *512;
return true;
}
/* Read not successful - report the error and return. */
/* NB we must fclose() after reporting to retain errno. */
/*@-mustfreefresh@ *//* see above */
fprintf(stderr, "%s: %s: %s: %s\n",
opts->program_name, size_file, _("failed to read sysfs size file"), strerror(errno));
(void) fclose(sysfs_fptr);
return false;
/*@+mustfreefresh@ */
}
#endif /* CAN_BUILD_SYSFS_FILENAME */
/*
* Try opening the block device and seeking to the end.
*/
device_fd = open(size_file, O_RDONLY); /* flawfinder: ignore */
/*
* flawfinder rationale: the filename is under the direct control of
* the operator by its nature, so we can't refuse to open symlinks
* etc as that would be counterintuitive.
*/
if (device_fd < 0) {
/*@-mustfreefresh@ *//* see above */
fprintf(stderr, "%s: %s: %s: %s\n",
opts->program_name, size_file, _("failed to open block device"), strerror(errno));
return false;
/*@+mustfreefresh@ */
}
device_size = (off_t) lseek(device_fd, 0, SEEK_END);
if (device_size < 0) {
/*@-mustfreefresh@ *//* see above */
fprintf(stderr, "%s: %s: %s: %s\n",
opts->program_name, size_file, _("failed to determine size of block device"), strerror(errno));
/* NB close() after reporting error, to preserve errno. */
(void) close(device_fd);
return false;
/*@+mustfreefresh@ */
}
(void) close(device_fd);
/* Use the size we found. */
opts->size = device_size;
return true;
}
/*
* Parse the given command-line arguments into an opts_t object, handling
* "help" and "version" options internally.
@@ -373,28 +530,16 @@ opts_t opts_parse(unsigned int argc, char **argv)
opts->delay_start = pv_getnum_interval(optarg);
break;
case 's':
/* Permit "@<filename>" as well as just a number. */
if ('@' == *optarg) {
if ('@' != *optarg) {
/* A number was passed, not "@<filename>". */
opts->size = pv_getnum_size(optarg, opts->decimal_units);
} else {
/* Permit "@<filename>". */
const char *size_file = 1 + optarg;
struct stat sb;
int rc;
rc = 0;
memset(&sb, 0, sizeof(sb));
rc = stat(size_file, &sb);
if (0 == rc) {
opts->size = (off_t) (sb.st_size);
} else {
/*@-mustfreefresh@ *//* see above */
fprintf(stderr, "%s: %s %s: %s\n",
opts->program_name,
_("failed to stat file"), size_file, strerror(errno));
if (!opts_use_size_of_file(opts, size_file)) {
opts_free(opts);
return NULL;
/*@+mustfreefresh@ */
}
} else {
opts->size = pv_getnum_size(optarg, opts->decimal_units);
}
break;
case 'l':
+13
View File
@@ -10,11 +10,15 @@
#include "pv.h"
#include "pv-internal.h"
/* We do not set this because it breaks "dd" - see below. */
/* #undef MAKE_OUTPUT_NONBLOCKING */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
/* alloc / realloc history buffer */
@@ -385,6 +389,15 @@ void pv_state_output_set(pvstate_t state, int fd, const char *name)
free(state->control.output_name);
state->control.output_fd = fd;
state->control.output_name = pv_strdup(name);
#ifdef MAKE_OUTPUT_NONBLOCKING
/*
* Try and make the output use non-blocking I/O.
*
* Note that this can cause problems with (broken) applications
* such as dd when used in a pipeline.
*/
fcntl(state->control.output_fd, F_SETFL, O_NONBLOCK | fcntl(state->control.output_fd, F_GETFL));
#endif /* MAKE_OUTPUT_NONBLOCKING */
}
void pv_state_average_rate_window_set(pvstate_t state, unsigned int val)
+22 -13
View File
@@ -181,6 +181,12 @@ static ssize_t pv__transfer_read_repeated(int fd, void *buf, size_t count)
* see if we can write any more, and keep trying, to make sure we empty the
* buffer as much as we can.
*
* While this is called after a successful write-possible select(), write() is
* not guaranteed to succeed for _all_ sizes; we may end up returning 0 if this
* occurs. (The first write() may return -1 / EINTR if the consumer doesn't
* read any data before our timeout and the buffer of whatever stdout is is
* near-full.) (see https://codeberg.org/a-j-wood/pv/pulls/93)
*
* If "sync_after_write" is true, we call fdatasync() after each write() (or
* fsync() if _POSIX_SYNCHRONIZED_IO is not > 0).
*
@@ -686,7 +692,11 @@ static int pv__transfer_write(pvstate_t state, bool *eof_in, bool *eof_out, long
state->transfer.write_position,
(size_t) (state->transfer.to_write),
state->control.sync_after_write);
debug("%s: %ld", "bytes written", (long) nwritten);
if (nwritten < 0) {
debug("%s: %ld: %s", "bytes written", (long) nwritten, strerror(errno));
} else {
debug("%s: %ld", "bytes written", (long) nwritten);
}
#if HAVE_SETITIMER
memset(&new_timer, 0, sizeof(new_timer));
new_timer.it_interval.tv_sec = 0;
@@ -704,13 +714,7 @@ static int pv__transfer_write(pvstate_t state, bool *eof_in, bool *eof_out, long
#endif /* HAVE_SETITIMER */
}
if (0 == nwritten) {
/*
* Write returned 0 - EOF on output.
*/
*eof_out = true;
return 1;
} else if (nwritten > 0) {
if (nwritten > 0) {
/*
* Write returned >0 - data successfully written.
*/
@@ -796,15 +800,20 @@ static int pv__transfer_write(pvstate_t state, bool *eof_in, bool *eof_out, long
}
/*
* If we reach this point, nwritten<0, so there was an error.
* If we reach this point, nwritten<=0, so there may be an error.
*/
/*
* If a write error occurred but it was EINTR or EAGAIN, just wait a
* bit and then return zero, since this was a transient error.
* If a write error occurred but it was EINTR or EAGAIN, or write(2)
* blocked on first write such that nwritten == 0, just wait a bit and
* then return zero, since this was a transient error.
*/
if ((EINTR == errno) || (EAGAIN == errno)) {
debug("%s: %s", "transient write error - waiting briefly", strerror(errno));
if ((0 == nwritten) || (EINTR == errno) || (EAGAIN == errno)) {
if (0 == nwritten) {
debug("%s", "attempted write blocked - waiting briefly");
} else {
debug("%s: %s", "transient write error - waiting briefly", strerror(errno));
}
(void) is_data_ready(-1, NULL, -1, NULL, 10000);
return 0;
}
+1
View File
@@ -478,6 +478,7 @@ int pv_watchpid_scanfds(pvstate_t state,
/*@-mustfreeonly@ *//* splint - this is not a leak, this is a new entry. */
info_array[use_idx].state->control.name = NULL;
info_array[use_idx].state->control.format_string = NULL;
info_array[use_idx].state->control.output_name = NULL;
/*@+mustfreeonly@ */
info_array[use_idx].state->control.default_format[0] = '\0';
use_format_string =