20 Commits
Author SHA1 Message Date
Andrew Wood b42399e9a9 Timestamp update. 2024-07-18 22:23:48 +01:00
Andrew Wood ba72056bf2 Version bump. 2024-07-18 22:10:57 +01:00
Andrew Wood b8e4a51228 Update line numbers. 2024-07-18 22:08:34 +01:00
Andrew Wood 0b12f7db42 Update TODO to reflect issue tracker. 2024-07-18 22:01:36 +01:00
Andrew Wood 5053cffdad Further clarification of #92, #93. 2024-07-17 07:45:13 +01:00
Andrew Wood 02f852604f Add #93. 2024-07-17 07:42:18 +01:00
Andrew Wood e4ab8c56a0 Minor adjustment to comments. 2024-07-17 07:41:48 +01:00
Andrew Wood 86016d41d7 Merge pull request 'Improve description and comments for blocking-write() after select()' (#93) from eborisch/pv:update-block-after-select into main
Reviewed-on: https://codeberg.org/a-j-wood/pv/pulls/93
2024-07-17 06:36:50 +00:00
Eric A. Borisch 3fdfd07443 Improve description and comments for blocking-write() after select() 2024-07-16 23:39:15 -05:00
Andrew Wood d801cdd722 Remove spurious strerror() call from debug report. 2024-07-16 22:44:10 +01:00
Andrew Wood 72e5078ce9 Move the MAKE_OUTPUT_NONBLOCKING code to state.c, as it can no longer work in main.c due to accessing internal structures; but still leave it switched off by default for now. 2024-07-16 22:41:31 +01:00
Andrew Wood a7c3f3dd35 Write the error from write() to the debugging output if nwritten is <0. 2024-07-16 22:23:51 +01:00
Andrew Wood 729fc10674 News item and acknowledgement for zero write bug fix (#92). 2024-07-16 22:03:56 +01:00
Andrew Wood 12f0312b00 Move the "stop at size" option setting to before the size calculation, otherwise if the size calculation tries to override that setting, it cannot do so (#91). 2024-07-16 21:58:47 +01:00
Andrew Wood 8c0e3e9dad When checking how many bytes were written, place the constant to the left of the equality check to match the rest of the code (this avoids accidental assignment if one equals sign is accidentally written instead of two), and write the appropriate debug message depending on whether the write was interrupted or it was empty. 2024-07-16 21:54:13 +01:00
Andrew Wood c7104f0c0d Merge pull request 'src/pv/transfer.c: timer going off returns with total_written==0; which is not an error.' (#92) from eborisch/pv:write-can-return-0 into main
Reviewed-on: https://codeberg.org/a-j-wood/pv/pulls/92
2024-07-16 20:47:32 +00:00
Andrew Wood 679638beb2 More details. 2024-07-16 21:42:23 +01:00
Andrew Wood f8fc5844b1 Re-order the output file descriptor setting and the size detection to correct the problem with output block device size detection that was broken in 1.8.10 (#91). 2024-07-16 21:39:29 +01:00
eborisch d86d8cf65a Clarify state. 2024-07-16 03:57:11 +00:00
eborisch 11e5b5fe95 src/pv/transfer.c: write(2) returning 0 is not an error
This is being hit easily on FreeBSD with pv sitting in a zfs send/recv pipeline. As write(2) returning 0 is not an error, handle it similar to returning -1 with EINTR or EAGAIN: wait a bit and try again.
2024-07-15 21:36:57 +00:00
12 changed files with 181 additions and 149 deletions
+1 -1
View File
@@ -4,7 +4,7 @@ dnl Copyright 2002-2008, 2010, 2012-2015, 2017, 2021, 2023-2024 Andrew Wood
dnl
dnl License GPLv3+: GNU GPL version 3 or later; see `docs/COPYING'.
AC_INIT([pv], [1.8.10], [pv@ivarch.com], [pv], [https://www.ivarch.com/programs/pv.shtml])
AC_INIT([pv], [1.8.12], [pv@ivarch.com], [pv], [https://www.ivarch.com/programs/pv.shtml])
AC_CONFIG_SRCDIR([src/include/config.h.in])
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_HEADERS([src/include/config.h])
+2
View File
@@ -92,5 +92,7 @@ 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))
---
+5
View File
@@ -1,3 +1,8 @@
### 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 "July 2024" Linux "User Manuals"
.SH NAME
pv \- monitor the progress of data through a pipe
.SH SYNOPSIS
+16 -16
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-07-18 22:11+0100\n"
"Language: de\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Date: 1999-06-01 15:18:29+0100\n"
@@ -254,7 +254,7 @@ 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"
@@ -372,7 +372,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 +380,7 @@ msgstr "Puffer konnte nicht allokiert werden"
msgid "b"
msgstr ""
#: src/pv/display.c:859 src/pv/transfer.c:596
#: src/pv/display.c:859 src/pv/transfer.c:602
msgid "B"
msgstr "B"
@@ -436,51 +436,51 @@ msgstr ""
msgid "pid"
msgstr ""
#: src/pv/state.c:36
#: src/pv/state.c:40
msgid "history structure allocation failed"
msgstr ""
#: src/pv/state.c: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"
+16 -16
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-07-18 22:11+0100\n"
"Language: fr\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Date: 1999-06-01 15:18:29+0100\n"
@@ -255,7 +255,7 @@ 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"
@@ -377,7 +377,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 +385,7 @@ msgstr "échec de l'allocation de mémoire tampon"
msgid "b"
msgstr ""
#: src/pv/display.c:859 src/pv/transfer.c:596
#: src/pv/display.c:859 src/pv/transfer.c:602
msgid "B"
msgstr "O"
@@ -441,51 +441,51 @@ msgstr ""
msgid "pid"
msgstr ""
#: src/pv/state.c:36
#: src/pv/state.c:40
msgid "history structure allocation failed"
msgstr "l'allocation de la structure de l'historique a échoué"
#: src/pv/state.c: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é"
+16 -16
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-07-18 22:11+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -248,7 +248,7 @@ 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 ""
@@ -361,7 +361,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 +369,7 @@ msgstr "nie udało się zaalokować bufora"
msgid "b"
msgstr ""
#: src/pv/display.c:859 src/pv/transfer.c:596
#: src/pv/display.c:859 src/pv/transfer.c:602
msgid "B"
msgstr "B"
@@ -426,52 +426,52 @@ msgstr ""
msgid "pid"
msgstr ""
#: src/pv/state.c:36
#: src/pv/state.c:40
msgid "history structure allocation failed"
msgstr ""
#: src/pv/state.c: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"
+16 -16
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-07-18 22:11+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -248,7 +248,7 @@ 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"
@@ -364,7 +364,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 +372,7 @@ msgstr "erro alocando o buffer"
msgid "b"
msgstr ""
#: src/pv/display.c:859 src/pv/transfer.c:596
#: src/pv/display.c:859 src/pv/transfer.c:602
msgid "B"
msgstr ""
@@ -428,51 +428,51 @@ msgstr ""
msgid "pid"
msgstr ""
#: src/pv/state.c:36
#: src/pv/state.c:40
msgid "history structure allocation failed"
msgstr ""
#: src/pv/state.c: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"
+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);
+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;
}