Group state structure into sub-structures to allow future changes to watchpid code that will do a better job of duplicating the relevant parts of the internal state for each fd.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Report-Msgid-Bugs-To: pv@ivarch.com\n"
|
||||
"POT-Creation-Date: 2023-10-14 00:07+0100\n"
|
||||
"POT-Creation-Date: 2023-10-14 01:21+0100\n"
|
||||
"Language: de\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Date: 1999-06-01 15:18:29+0100\n"
|
||||
@@ -364,31 +364,31 @@ msgstr ""
|
||||
msgid "yzafpnum KMGTPEZY"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:701 src/pv/transfer.c:903
|
||||
#: src/pv/display.c:704 src/pv/transfer.c:911
|
||||
msgid "buffer allocation failed"
|
||||
msgstr "Puffer konnte nicht allokiert werden"
|
||||
|
||||
#: src/pv/display.c:763
|
||||
#: src/pv/display.c:767
|
||||
msgid "b"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:768 src/pv/transfer.c:591
|
||||
#: src/pv/display.c:772 src/pv/transfer.c:595
|
||||
msgid "B"
|
||||
msgstr "B"
|
||||
|
||||
#: src/pv/display.c:820 src/pv/display.c:833
|
||||
#: src/pv/display.c:825 src/pv/display.c:838
|
||||
msgid "b/s"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:824 src/pv/display.c:838
|
||||
#: src/pv/display.c:829 src/pv/display.c:843
|
||||
msgid "/s"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:824 src/pv/display.c:838
|
||||
#: src/pv/display.c:829 src/pv/display.c:843
|
||||
msgid "B/s"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:875 src/pv/display.c:879 src/pv/display.c:938
|
||||
#: src/pv/display.c:880 src/pv/display.c:884 src/pv/display.c:943
|
||||
msgid "ETA"
|
||||
msgstr "ETA"
|
||||
|
||||
@@ -420,7 +420,7 @@ msgstr ""
|
||||
msgid "(stdin)"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/loop.c:545 src/pv/loop.c:599 src/pv/loop.c:641 src/pv/watchpid.c:73
|
||||
#: src/pv/loop.c:546 src/pv/loop.c:601 src/pv/loop.c:643 src/pv/watchpid.c:73
|
||||
#: src/pv/watchpid.c:83 src/pv/watchpid.c:94 src/pv/watchpid.c:102
|
||||
#: src/pv/watchpid.c:139 src/pv/watchpid.c:150 src/pv/watchpid.c:158
|
||||
#: src/pv/watchpid.c:169 src/pv/watchpid.c:256 src/pv/watchpid.c:264
|
||||
@@ -432,43 +432,43 @@ msgstr ""
|
||||
msgid "history structure allocation failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/state.c:385 src/pv/state.c:395
|
||||
#: src/pv/state.c:385 src/pv/state.c:396
|
||||
msgid "file list allocation failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:453
|
||||
#: src/pv/transfer.c:457
|
||||
msgid "read failed"
|
||||
msgstr "read-Aufruf fehlgeschlagen"
|
||||
|
||||
#: src/pv/transfer.c:476
|
||||
#: src/pv/transfer.c:480
|
||||
msgid "warning: read errors detected"
|
||||
msgstr "warnung: lesefehler erkannt"
|
||||
|
||||
#: src/pv/transfer.c:492
|
||||
#: src/pv/transfer.c:496
|
||||
msgid "file is not seekable"
|
||||
msgstr "datei ist nicht durchsuchbar"
|
||||
|
||||
#: src/pv/transfer.c:570
|
||||
#: src/pv/transfer.c:574
|
||||
msgid "failed to seek past error"
|
||||
msgstr "konnte den Fehler nicht überwinden"
|
||||
|
||||
#: src/pv/transfer.c:590
|
||||
#: src/pv/transfer.c:594
|
||||
msgid "skipped past read error"
|
||||
msgstr "über den Lesefehler hinaus verschoben"
|
||||
|
||||
#: src/pv/transfer.c:630
|
||||
#: src/pv/transfer.c:634
|
||||
msgid "no transfer buffer allocated"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:643
|
||||
#: src/pv/transfer.c:647
|
||||
msgid "failed to set alarm signal handler"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:768
|
||||
#: src/pv/transfer.c:775
|
||||
msgid "write failed"
|
||||
msgstr "write-Aufruf fehlgeschlagen"
|
||||
|
||||
#: src/pv/transfer.c:1000
|
||||
#: src/pv/transfer.c:1008
|
||||
msgid "select call failed"
|
||||
msgstr "select-Aufruf fehlgeschlagen"
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Report-Msgid-Bugs-To: pv@ivarch.com\n"
|
||||
"POT-Creation-Date: 2023-10-14 00:07+0100\n"
|
||||
"POT-Creation-Date: 2023-10-14 01:21+0100\n"
|
||||
"Language: fr\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Date: 1999-06-01 15:18:29+0100\n"
|
||||
@@ -365,31 +365,31 @@ msgstr ""
|
||||
msgid "yzafpnum KMGTPEZY"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:701 src/pv/transfer.c:903
|
||||
#: src/pv/display.c:704 src/pv/transfer.c:911
|
||||
msgid "buffer allocation failed"
|
||||
msgstr "l'allocation de mémoire tampon a échoué"
|
||||
|
||||
#: src/pv/display.c:763
|
||||
#: src/pv/display.c:767
|
||||
msgid "b"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:768 src/pv/transfer.c:591
|
||||
#: src/pv/display.c:772 src/pv/transfer.c:595
|
||||
msgid "B"
|
||||
msgstr "O"
|
||||
|
||||
#: src/pv/display.c:820 src/pv/display.c:833
|
||||
#: src/pv/display.c:825 src/pv/display.c:838
|
||||
msgid "b/s"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:824 src/pv/display.c:838
|
||||
#: src/pv/display.c:829 src/pv/display.c:843
|
||||
msgid "/s"
|
||||
msgstr "/s"
|
||||
|
||||
#: src/pv/display.c:824 src/pv/display.c:838
|
||||
#: src/pv/display.c:829 src/pv/display.c:843
|
||||
msgid "B/s"
|
||||
msgstr "O/s"
|
||||
|
||||
#: src/pv/display.c:875 src/pv/display.c:879 src/pv/display.c:938
|
||||
#: src/pv/display.c:880 src/pv/display.c:884 src/pv/display.c:943
|
||||
msgid "ETA"
|
||||
msgstr "ETA"
|
||||
|
||||
@@ -421,7 +421,7 @@ msgstr ""
|
||||
msgid "(stdin)"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/loop.c:545 src/pv/loop.c:599 src/pv/loop.c:641 src/pv/watchpid.c:73
|
||||
#: src/pv/loop.c:546 src/pv/loop.c:601 src/pv/loop.c:643 src/pv/watchpid.c:73
|
||||
#: src/pv/watchpid.c:83 src/pv/watchpid.c:94 src/pv/watchpid.c:102
|
||||
#: src/pv/watchpid.c:139 src/pv/watchpid.c:150 src/pv/watchpid.c:158
|
||||
#: src/pv/watchpid.c:169 src/pv/watchpid.c:256 src/pv/watchpid.c:264
|
||||
@@ -433,43 +433,43 @@ msgstr ""
|
||||
msgid "history structure allocation failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/state.c:385 src/pv/state.c:395
|
||||
#: src/pv/state.c:385 src/pv/state.c:396
|
||||
msgid "file list allocation failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:453
|
||||
#: src/pv/transfer.c:457
|
||||
msgid "read failed"
|
||||
msgstr "la lecture a échoué"
|
||||
|
||||
#: src/pv/transfer.c:476
|
||||
#: src/pv/transfer.c:480
|
||||
msgid "warning: read errors detected"
|
||||
msgstr "avertissement: erreurs de lecture détectées"
|
||||
|
||||
#: src/pv/transfer.c:492
|
||||
#: src/pv/transfer.c:496
|
||||
msgid "file is not seekable"
|
||||
msgstr "ne peut pas se déplacer dans le fichier"
|
||||
|
||||
#: src/pv/transfer.c:570
|
||||
#: src/pv/transfer.c:574
|
||||
msgid "failed to seek past error"
|
||||
msgstr "n'a pas réussi à dépasser l'erreur"
|
||||
|
||||
#: src/pv/transfer.c:590
|
||||
#: src/pv/transfer.c:594
|
||||
msgid "skipped past read error"
|
||||
msgstr "erreur de lecture dépassée"
|
||||
|
||||
#: src/pv/transfer.c:630
|
||||
#: src/pv/transfer.c:634
|
||||
msgid "no transfer buffer allocated"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:643
|
||||
#: src/pv/transfer.c:647
|
||||
msgid "failed to set alarm signal handler"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:768
|
||||
#: src/pv/transfer.c:775
|
||||
msgid "write failed"
|
||||
msgstr "l'écriture a échoué"
|
||||
|
||||
#: src/pv/transfer.c:1000
|
||||
#: src/pv/transfer.c:1008
|
||||
msgid "select call failed"
|
||||
msgstr "appel de sélection a échoué"
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: pv@ivarch.com\n"
|
||||
"POT-Creation-Date: 2023-10-14 00:07+0100\n"
|
||||
"POT-Creation-Date: 2023-10-14 01:21+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"
|
||||
@@ -353,31 +353,31 @@ msgstr ""
|
||||
msgid "yzafpnum KMGTPEZY"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:701 src/pv/transfer.c:903
|
||||
#: src/pv/display.c:704 src/pv/transfer.c:911
|
||||
msgid "buffer allocation failed"
|
||||
msgstr "nie udało się zaalokować bufora"
|
||||
|
||||
#: src/pv/display.c:763
|
||||
#: src/pv/display.c:767
|
||||
msgid "b"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:768 src/pv/transfer.c:591
|
||||
#: src/pv/display.c:772 src/pv/transfer.c:595
|
||||
msgid "B"
|
||||
msgstr "B"
|
||||
|
||||
#: src/pv/display.c:820 src/pv/display.c:833
|
||||
#: src/pv/display.c:825 src/pv/display.c:838
|
||||
msgid "b/s"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:824 src/pv/display.c:838
|
||||
#: src/pv/display.c:829 src/pv/display.c:843
|
||||
msgid "/s"
|
||||
msgstr "/s"
|
||||
|
||||
#: src/pv/display.c:824 src/pv/display.c:838
|
||||
#: src/pv/display.c:829 src/pv/display.c:843
|
||||
msgid "B/s"
|
||||
msgstr "B/s"
|
||||
|
||||
#: src/pv/display.c:875 src/pv/display.c:879 src/pv/display.c:938
|
||||
#: src/pv/display.c:880 src/pv/display.c:884 src/pv/display.c:943
|
||||
msgid "ETA"
|
||||
msgstr "ETA"
|
||||
|
||||
@@ -410,7 +410,7 @@ msgstr ""
|
||||
msgid "(stdin)"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/loop.c:545 src/pv/loop.c:599 src/pv/loop.c:641 src/pv/watchpid.c:73
|
||||
#: src/pv/loop.c:546 src/pv/loop.c:601 src/pv/loop.c:643 src/pv/watchpid.c:73
|
||||
#: src/pv/watchpid.c:83 src/pv/watchpid.c:94 src/pv/watchpid.c:102
|
||||
#: src/pv/watchpid.c:139 src/pv/watchpid.c:150 src/pv/watchpid.c:158
|
||||
#: src/pv/watchpid.c:169 src/pv/watchpid.c:256 src/pv/watchpid.c:264
|
||||
@@ -422,43 +422,43 @@ msgstr ""
|
||||
msgid "history structure allocation failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/state.c:385 src/pv/state.c:395
|
||||
#: src/pv/state.c:385 src/pv/state.c:396
|
||||
msgid "file list allocation failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:453
|
||||
#: src/pv/transfer.c:457
|
||||
msgid "read failed"
|
||||
msgstr "błąd odczytu"
|
||||
|
||||
#: src/pv/transfer.c:476
|
||||
#: src/pv/transfer.c:480
|
||||
msgid "warning: read errors detected"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:492
|
||||
#: src/pv/transfer.c:496
|
||||
msgid "file is not seekable"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:570
|
||||
#: src/pv/transfer.c:574
|
||||
msgid "failed to seek past error"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:590
|
||||
#: src/pv/transfer.c:594
|
||||
msgid "skipped past read error"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:630
|
||||
#: src/pv/transfer.c:634
|
||||
msgid "no transfer buffer allocated"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:643
|
||||
#: src/pv/transfer.c:647
|
||||
msgid "failed to set alarm signal handler"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:768
|
||||
#: src/pv/transfer.c:775
|
||||
msgid "write failed"
|
||||
msgstr "błąd zapisu"
|
||||
|
||||
#: src/pv/transfer.c:1000
|
||||
#: src/pv/transfer.c:1008
|
||||
msgid "select call failed"
|
||||
msgstr "nie udało się wywołać funkcji select"
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: pv@ivarch.com\n"
|
||||
"POT-Creation-Date: 2023-10-14 00:07+0100\n"
|
||||
"POT-Creation-Date: 2023-10-14 01:21+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"
|
||||
@@ -356,31 +356,31 @@ msgstr ""
|
||||
msgid "yzafpnum KMGTPEZY"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:701 src/pv/transfer.c:903
|
||||
#: src/pv/display.c:704 src/pv/transfer.c:911
|
||||
msgid "buffer allocation failed"
|
||||
msgstr "erro alocando o buffer"
|
||||
|
||||
#: src/pv/display.c:763
|
||||
#: src/pv/display.c:767
|
||||
msgid "b"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:768 src/pv/transfer.c:591
|
||||
#: src/pv/display.c:772 src/pv/transfer.c:595
|
||||
msgid "B"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:820 src/pv/display.c:833
|
||||
#: src/pv/display.c:825 src/pv/display.c:838
|
||||
msgid "b/s"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:824 src/pv/display.c:838
|
||||
#: src/pv/display.c:829 src/pv/display.c:843
|
||||
msgid "/s"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/display.c:824 src/pv/display.c:838
|
||||
#: src/pv/display.c:829 src/pv/display.c:843
|
||||
msgid "B/s"
|
||||
msgstr "B/s"
|
||||
|
||||
#: src/pv/display.c:875 src/pv/display.c:879 src/pv/display.c:938
|
||||
#: src/pv/display.c:880 src/pv/display.c:884 src/pv/display.c:943
|
||||
msgid "ETA"
|
||||
msgstr "ETA"
|
||||
|
||||
@@ -412,7 +412,7 @@ msgstr ""
|
||||
msgid "(stdin)"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/loop.c:545 src/pv/loop.c:599 src/pv/loop.c:641 src/pv/watchpid.c:73
|
||||
#: src/pv/loop.c:546 src/pv/loop.c:601 src/pv/loop.c:643 src/pv/watchpid.c:73
|
||||
#: src/pv/watchpid.c:83 src/pv/watchpid.c:94 src/pv/watchpid.c:102
|
||||
#: src/pv/watchpid.c:139 src/pv/watchpid.c:150 src/pv/watchpid.c:158
|
||||
#: src/pv/watchpid.c:169 src/pv/watchpid.c:256 src/pv/watchpid.c:264
|
||||
@@ -424,43 +424,43 @@ msgstr ""
|
||||
msgid "history structure allocation failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/state.c:385 src/pv/state.c:395
|
||||
#: src/pv/state.c:385 src/pv/state.c:396
|
||||
msgid "file list allocation failed"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:453
|
||||
#: src/pv/transfer.c:457
|
||||
msgid "read failed"
|
||||
msgstr "erro de leitura"
|
||||
|
||||
#: src/pv/transfer.c:476
|
||||
#: src/pv/transfer.c:480
|
||||
msgid "warning: read errors detected"
|
||||
msgstr "aviso: erros de leitura detectados"
|
||||
|
||||
#: src/pv/transfer.c:492
|
||||
#: src/pv/transfer.c:496
|
||||
msgid "file is not seekable"
|
||||
msgstr "não pode mover dentro do arquivo"
|
||||
|
||||
#: src/pv/transfer.c:570
|
||||
#: src/pv/transfer.c:574
|
||||
msgid "failed to seek past error"
|
||||
msgstr "não pode ir além do erro"
|
||||
|
||||
#: src/pv/transfer.c:590
|
||||
#: src/pv/transfer.c:594
|
||||
msgid "skipped past read error"
|
||||
msgstr "ignorado erro de leitura"
|
||||
|
||||
#: src/pv/transfer.c:630
|
||||
#: src/pv/transfer.c:634
|
||||
msgid "no transfer buffer allocated"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:643
|
||||
#: src/pv/transfer.c:647
|
||||
msgid "failed to set alarm signal handler"
|
||||
msgstr ""
|
||||
|
||||
#: src/pv/transfer.c:768
|
||||
#: src/pv/transfer.c:775
|
||||
msgid "write failed"
|
||||
msgstr "erro de gravação"
|
||||
|
||||
#: src/pv/transfer.c:1000
|
||||
#: src/pv/transfer.c:1008
|
||||
msgid "select call failed"
|
||||
msgstr "erro na chamada da função select"
|
||||
|
||||
|
||||
+158
-135
@@ -84,136 +84,154 @@ struct pvcursorstate_s {
|
||||
* Structure for holding PV internal state. Opaque outside the PV library.
|
||||
*/
|
||||
struct pvstate_s {
|
||||
/******************
|
||||
* Program status *
|
||||
******************/
|
||||
struct {
|
||||
/*@only@*/ char *program_name; /* program name for error reporting */
|
||||
char cwd[PV_SIZEOF_CWD]; /* current working directory for relative path */
|
||||
int current_input_file; /* index of current file being read */
|
||||
int exit_status; /* exit status to give (0=OK) */
|
||||
} status;
|
||||
|
||||
/***************
|
||||
* Input files *
|
||||
***************/
|
||||
unsigned int input_file_count; /* number of input files */
|
||||
/*@only@*/ /*@null@*/ char **input_files; /* input files */
|
||||
struct {
|
||||
unsigned int file_count; /* number of input files */
|
||||
/*@only@*/ /*@null@*/ char **filename; /* input filenames */
|
||||
} files;
|
||||
|
||||
/*******************
|
||||
* Program control *
|
||||
*******************/
|
||||
bool force; /* display even if not on terminal */
|
||||
bool cursor; /* use cursor positioning */
|
||||
bool numeric; /* numeric output only */
|
||||
bool wait; /* wait for data before display */
|
||||
bool linemode; /* count lines instead of bytes */
|
||||
bool bits; /* report bits instead of bytes */
|
||||
bool null_terminated_lines; /* lines are null-terminated */
|
||||
bool no_display; /* do nothing other than pipe data */
|
||||
unsigned int skip_errors; /* skip read errors counter */
|
||||
off_t error_skip_block; /* skip block size, 0 for adaptive */
|
||||
bool stop_at_size; /* set if we stop at "size" bytes */
|
||||
bool sync_after_write; /* set if we sync after every write */
|
||||
bool direct_io; /* set if O_DIRECT is to be used */
|
||||
bool direct_io_changed; /* set when direct_io is changed */
|
||||
bool no_splice; /* never use splice() */
|
||||
bool discard_input; /* write nothing to stdout */
|
||||
off_t rate_limit; /* rate limit, in bytes per second */
|
||||
size_t target_buffer_size; /* buffer size (0=default) */
|
||||
off_t size; /* total size of data */
|
||||
double interval; /* interval between updates */
|
||||
double delay_start; /* delay before first display */
|
||||
pid_t watch_pid; /* process to watch fds of */
|
||||
int watch_fd; /* fd to watch */
|
||||
unsigned int width; /* screen width */
|
||||
unsigned int height; /* screen height */
|
||||
bool width_set_manually; /* width was set manually, not detected */
|
||||
bool height_set_manually; /* height was set manually, not detected */
|
||||
/*@only@*/ /*@null@*/ char *name; /* display name */
|
||||
char default_format[PV_SIZEOF_DEFAULT_FORMAT]; /* default format string */
|
||||
/*@only@*/ /*@null@*/ char *format_string; /* output format string */
|
||||
|
||||
/******************
|
||||
* Program status *
|
||||
******************/
|
||||
/*@only@*/ char *program_name; /* program name for error reporting */
|
||||
char cwd[PV_SIZEOF_CWD]; /* current working directory for relative path */
|
||||
int current_input_file; /* index of current file being read */
|
||||
int exit_status; /* exit status to give (0=OK) */
|
||||
struct {
|
||||
bool force; /* display even if not on terminal */
|
||||
bool cursor; /* use cursor positioning */
|
||||
bool numeric; /* numeric output only */
|
||||
bool wait; /* wait for data before display */
|
||||
bool linemode; /* count lines instead of bytes */
|
||||
bool bits; /* report bits instead of bytes */
|
||||
bool null_terminated_lines; /* lines are null-terminated */
|
||||
bool no_display; /* do nothing other than pipe data */
|
||||
unsigned int skip_errors; /* skip read errors counter */
|
||||
off_t error_skip_block; /* skip block size, 0 for adaptive */
|
||||
bool stop_at_size; /* set if we stop at "size" bytes */
|
||||
bool sync_after_write; /* set if we sync after every write */
|
||||
bool direct_io; /* set if O_DIRECT is to be used */
|
||||
bool direct_io_changed; /* set when direct_io is changed */
|
||||
bool no_splice; /* never use splice() */
|
||||
bool discard_input; /* write nothing to stdout */
|
||||
off_t rate_limit; /* rate limit, in bytes per second */
|
||||
size_t target_buffer_size; /* buffer size (0=default) */
|
||||
off_t size; /* total size of data */
|
||||
double interval; /* interval between updates */
|
||||
double delay_start; /* delay before first display */
|
||||
pid_t watch_pid; /* process to watch fds of */
|
||||
int watch_fd; /* fd to watch */
|
||||
unsigned int width; /* screen width */
|
||||
unsigned int height; /* screen height */
|
||||
bool width_set_manually; /* width was set manually, not detected */
|
||||
bool height_set_manually; /* height was set manually, not detected */
|
||||
/*@only@*/ /*@null@*/ char *name; /* display name */
|
||||
char default_format[PV_SIZEOF_DEFAULT_FORMAT]; /* default format string */
|
||||
/*@only@*/ /*@null@*/ char *format_string; /* output format string */
|
||||
} control;
|
||||
|
||||
/*******************
|
||||
* Signal handling *
|
||||
*******************/
|
||||
int pv_sig_old_stderr; /* see pv_sig_ttou() */
|
||||
bool pv_tty_tostop_added; /* whether we had to set TOSTOP on the terminal */
|
||||
struct timespec pv_sig_tstp_time; /* see pv_sig_tstp() / __cont() */
|
||||
struct timespec pv_sig_toffset; /* total time spent stopped */
|
||||
volatile sig_atomic_t pv_sig_newsize; /* whether we need to get term size again */
|
||||
volatile sig_atomic_t pv_sig_abort; /* whether we need to abort right now */
|
||||
volatile sig_atomic_t reparse_display; /* whether to re-check format string */
|
||||
struct {
|
||||
int old_stderr; /* see pv_sig_ttou() */
|
||||
bool pv_tty_tostop_added; /* whether we had to set TOSTOP on the terminal */
|
||||
struct timespec tstp_time; /* see pv_sig_tstp() / __cont() */
|
||||
struct timespec toffset; /* total time spent stopped */
|
||||
#ifdef SA_SIGINFO
|
||||
volatile sig_atomic_t pv_sig_rxusr2; /* whether SIGUSR2 was received */
|
||||
volatile pid_t pv_sig_sender; /* PID of sending process for SIGUSR2 */
|
||||
volatile sig_atomic_t rxusr2; /* whether SIGUSR2 was received */
|
||||
volatile pid_t sender; /* PID of sending process for SIGUSR2 */
|
||||
#endif
|
||||
struct sigaction pv_sig_old_sigpipe;
|
||||
struct sigaction pv_sig_old_sigttou;
|
||||
struct sigaction pv_sig_old_sigtstp;
|
||||
struct sigaction pv_sig_old_sigcont;
|
||||
struct sigaction pv_sig_old_sigwinch;
|
||||
struct sigaction pv_sig_old_sigint;
|
||||
struct sigaction pv_sig_old_sighup;
|
||||
struct sigaction pv_sig_old_sigterm;
|
||||
struct sigaction old_sigpipe;
|
||||
struct sigaction old_sigttou;
|
||||
struct sigaction old_sigtstp;
|
||||
struct sigaction old_sigcont;
|
||||
struct sigaction old_sigwinch;
|
||||
struct sigaction old_sigint;
|
||||
struct sigaction old_sighup;
|
||||
struct sigaction old_sigterm;
|
||||
#ifdef SA_SIGINFO
|
||||
struct sigaction pv_sig_old_sigusr2;
|
||||
struct sigaction old_sigusr2;
|
||||
#endif
|
||||
} signal;
|
||||
|
||||
/*******************
|
||||
* Transient flags *
|
||||
*******************/
|
||||
struct {
|
||||
volatile sig_atomic_t reparse_display; /* whether to re-check format string */
|
||||
volatile sig_atomic_t terminal_resized; /* whether we need to get term size again */
|
||||
volatile sig_atomic_t trigger_exit; /* whether we need to abort right now */
|
||||
} flag;
|
||||
|
||||
/*****************
|
||||
* Display state *
|
||||
*****************/
|
||||
long percentage;
|
||||
long double prev_elapsed_sec;
|
||||
long double prev_rate;
|
||||
long double prev_trans;
|
||||
|
||||
/* Keep track of progress over last intervals to compute current average rate. */
|
||||
/*@null@*/ pvhistory_t *history; /* state at previous intervals (circular buffer) */
|
||||
unsigned int history_len; /* total size */
|
||||
int history_interval; /* seconds between each history entry */
|
||||
int history_first;
|
||||
int history_last;
|
||||
long double current_avg_rate; /* current average rate over last history intervals */
|
||||
|
||||
off_t initial_offset;
|
||||
/*@only@*/ char *display_buffer;
|
||||
long display_buffer_size;
|
||||
size_t lastoutput_length; /* number of last-output bytes to show */
|
||||
char lastoutput_buffer[PV_SIZEOF_LASTOUTPUT_BUFFER];
|
||||
int prev_width; /* screen width last time we were called */
|
||||
int prev_length; /* length of last string we output */
|
||||
char str_name[PV_SIZEOF_STR_NAME];
|
||||
char str_transferred[PV_SIZEOF_STR_TRANSFERRED];
|
||||
char str_bufpercent[PV_SIZEOF_STR_BUFPERCENT];
|
||||
char str_timer[PV_SIZEOF_STR_TIMER];
|
||||
char str_rate[PV_SIZEOF_STR_RATE];
|
||||
char str_average_rate[PV_SIZEOF_STR_AVERAGE_RATE];
|
||||
char str_progress[PV_SIZEOF_STR_PROGRESS];
|
||||
char str_lastoutput[PV_SIZEOF_STR_LASTOUTPUT];
|
||||
char str_eta[PV_SIZEOF_STR_ETA];
|
||||
char str_fineta[PV_SIZEOF_STR_FINETA];
|
||||
unsigned long components_used; /* bitmask of components used */
|
||||
struct {
|
||||
const char *string;
|
||||
int length;
|
||||
} format[PV_FORMAT_ARRAY_MAX];
|
||||
bool display_visible; /* set once anything written to terminal */
|
||||
long percentage;
|
||||
long double prev_elapsed_sec;
|
||||
long double prev_rate;
|
||||
long double prev_trans;
|
||||
|
||||
/* Keep track of progress over last intervals to compute current average rate. */
|
||||
/*@null@*/ pvhistory_t *history; /* state at previous intervals (circular buffer) */
|
||||
unsigned int history_len; /* total size */
|
||||
int history_interval; /* seconds between each history entry */
|
||||
int history_first;
|
||||
int history_last;
|
||||
long double current_avg_rate; /* current average rate over last history intervals */
|
||||
|
||||
off_t initial_offset;
|
||||
/*@only@*/ char *display_buffer;
|
||||
long display_buffer_size;
|
||||
size_t lastoutput_length; /* number of last-output bytes to show */
|
||||
char lastoutput_buffer[PV_SIZEOF_LASTOUTPUT_BUFFER];
|
||||
int prev_width; /* screen width last time we were called */
|
||||
int prev_length; /* length of last string we output */
|
||||
char str_name[PV_SIZEOF_STR_NAME];
|
||||
char str_transferred[PV_SIZEOF_STR_TRANSFERRED];
|
||||
char str_bufpercent[PV_SIZEOF_STR_BUFPERCENT];
|
||||
char str_timer[PV_SIZEOF_STR_TIMER];
|
||||
char str_rate[PV_SIZEOF_STR_RATE];
|
||||
char str_average_rate[PV_SIZEOF_STR_AVERAGE_RATE];
|
||||
char str_progress[PV_SIZEOF_STR_PROGRESS];
|
||||
char str_lastoutput[PV_SIZEOF_STR_LASTOUTPUT];
|
||||
char str_eta[PV_SIZEOF_STR_ETA];
|
||||
char str_fineta[PV_SIZEOF_STR_FINETA];
|
||||
unsigned long components_used; /* bitmask of components used */
|
||||
struct {
|
||||
const char *string;
|
||||
int length;
|
||||
} format[PV_FORMAT_ARRAY_MAX];
|
||||
bool display_visible; /* set once anything written to terminal */
|
||||
} display;
|
||||
|
||||
/********************
|
||||
* Cursor/IPC state *
|
||||
********************/
|
||||
struct {
|
||||
#ifdef HAVE_IPC
|
||||
int crs_shmid; /* ID of our shared memory segment */
|
||||
int crs_pvcount; /* number of `pv' processes in total */
|
||||
int crs_pvmax; /* highest number of `pv's seen */
|
||||
/*@keep@*/ /*@null@*/ struct pvcursorstate_s *crs_shared; /* data shared between instances */
|
||||
int crs_y_lastread; /* last value of _y_top seen */
|
||||
int crs_y_offset; /* our Y offset from this top position */
|
||||
int crs_needreinit; /* counter if we need to reinit cursor pos */
|
||||
bool crs_noipc; /* set if we can't use IPC */
|
||||
int shmid; /* ID of our shared memory segment */
|
||||
int pvcount; /* number of `pv' processes in total */
|
||||
int pvmax; /* highest number of `pv's seen */
|
||||
/*@keep@*/ /*@null@*/ struct pvcursorstate_s *shared; /* data shared between instances */
|
||||
int y_lastread; /* last value of _y_top seen */
|
||||
int y_offset; /* our Y offset from this top position */
|
||||
int needreinit; /* counter if we need to reinit cursor pos */
|
||||
bool noipc; /* set if we can't use IPC */
|
||||
#endif /* HAVE_IPC */
|
||||
int crs_lock_fd; /* fd of lockfile, -1 if none open */
|
||||
char crs_lock_file[PV_SIZEOF_CRS_LOCK_FILE];
|
||||
int crs_y_start; /* our initial Y coordinate */
|
||||
int lock_fd; /* fd of lockfile, -1 if none open */
|
||||
char lock_file[PV_SIZEOF_CRS_LOCK_FILE];
|
||||
int y_start; /* our initial Y coordinate */
|
||||
} cursor;
|
||||
|
||||
/*******************
|
||||
* Transfer state *
|
||||
@@ -233,40 +251,45 @@ struct pvstate_s {
|
||||
* is the offset in the buffer that we've written data up to. It
|
||||
* will always be less than or equal to read_position.
|
||||
*/
|
||||
/*@only@*/ /*@null@*/ char *transfer_buffer; /* data transfer buffer */
|
||||
size_t buffer_size; /* size of buffer */
|
||||
size_t read_position; /* amount of data in buffer */
|
||||
size_t write_position; /* buffered data written */
|
||||
struct {
|
||||
/*@only@*/ /*@null@*/ char *transfer_buffer; /* data transfer buffer */
|
||||
size_t buffer_size; /* size of buffer */
|
||||
size_t read_position; /* amount of data in buffer */
|
||||
size_t write_position; /* buffered data written */
|
||||
|
||||
/*
|
||||
* While reading from a file descriptor we keep track of how many
|
||||
* times in a row we've seen errors (read_errors_in_a_row), and
|
||||
* whether or not we have put a warning on stderr about read errors
|
||||
* on this fd (read_error_warning_shown).
|
||||
*
|
||||
* Whenever the active file descriptor changes from
|
||||
* last_read_skip_fd, we reset read_errors_in_a_row to 0 and
|
||||
* read_error_warning_shown to false for the new file descriptor and
|
||||
* set last_read_skip_fd to the new fd number.
|
||||
*
|
||||
* This way, we're treating each input file separately.
|
||||
*/
|
||||
int last_read_skip_fd;
|
||||
off_t read_errors_in_a_row;
|
||||
bool read_error_warning_shown;
|
||||
/*
|
||||
* While reading from a file descriptor we keep track of how
|
||||
* many times in a row we've seen errors
|
||||
* (read_errors_in_a_row), and whether or not we have put a
|
||||
* warning on stderr about read errors on this fd
|
||||
* (read_error_warning_shown).
|
||||
*
|
||||
* Whenever the active file descriptor changes from
|
||||
* last_read_skip_fd, we reset read_errors_in_a_row to 0 and
|
||||
* read_error_warning_shown to false for the new file
|
||||
* descriptor and set last_read_skip_fd to the new fd
|
||||
* number.
|
||||
*
|
||||
* This way, we're treating each input file separately.
|
||||
*/
|
||||
int last_read_skip_fd;
|
||||
off_t read_errors_in_a_row;
|
||||
bool read_error_warning_shown;
|
||||
#ifdef HAVE_SPLICE
|
||||
/*
|
||||
* These variables are used to keep track of whether splice() was
|
||||
* used; splice_failed_fd is the file descriptor that splice() last
|
||||
* failed on, so that we don't keep trying to use it on an fd that
|
||||
* doesn't support it, and splice_used is set to true if splice()
|
||||
* was used this time within pv_transfer().
|
||||
*/
|
||||
int splice_failed_fd;
|
||||
bool splice_used;
|
||||
/*
|
||||
* These variables are used to keep track of whether
|
||||
* splice() was used; splice_failed_fd is the file
|
||||
* descriptor that splice() last failed on, so that we don't
|
||||
* keep trying to use it on an fd that doesn't support it,
|
||||
* and splice_used is set to true if splice() was used this
|
||||
* time within pv_transfer().
|
||||
*/
|
||||
int splice_failed_fd;
|
||||
bool splice_used;
|
||||
#endif
|
||||
ssize_t to_write; /* max to write this time around */
|
||||
ssize_t written; /* bytes sent to stdout this time */
|
||||
ssize_t to_write; /* max to write this time around */
|
||||
ssize_t written; /* bytes sent to stdout this time */
|
||||
} transfer;
|
||||
};
|
||||
|
||||
|
||||
|
||||
+99
-99
@@ -79,18 +79,18 @@ static void pv_crs_open_lockfile(pvstate_t state, int fd)
|
||||
char *tmpdir;
|
||||
int openflags;
|
||||
|
||||
state->crs_lock_fd = -1;
|
||||
state->cursor.lock_fd = -1;
|
||||
|
||||
ttydev = ttyname(fd);
|
||||
if (!ttydev) {
|
||||
if (!state->force) {
|
||||
if (!state->control.force) {
|
||||
pv_error(state, "%s: %s", _("failed to get terminal name"), strerror(errno));
|
||||
}
|
||||
/*
|
||||
* If we don't know our terminal name, we can neither do IPC
|
||||
* nor make a lock file, so turn off cursor positioning.
|
||||
*/
|
||||
state->cursor = 0;
|
||||
state->control.cursor = 0;
|
||||
debug("%s", "ttyname failed - cursor positioning disabled");
|
||||
return;
|
||||
}
|
||||
@@ -104,8 +104,8 @@ static void pv_crs_open_lockfile(pvstate_t state, int fd)
|
||||
*/
|
||||
tmpdir = "/tmp";
|
||||
|
||||
memset(state->crs_lock_file, 0, PV_SIZEOF_CRS_LOCK_FILE);
|
||||
(void) pv_snprintf(state->crs_lock_file,
|
||||
memset(state->cursor.lock_file, 0, PV_SIZEOF_CRS_LOCK_FILE);
|
||||
(void) pv_snprintf(state->cursor.lock_file,
|
||||
PV_SIZEOF_CRS_LOCK_FILE, "%s/pv-%s-%i.lock", tmpdir, basename(ttydev), (int) geteuid());
|
||||
|
||||
/*
|
||||
@@ -117,7 +117,7 @@ static void pv_crs_open_lockfile(pvstate_t state, int fd)
|
||||
openflags = O_RDWR | O_CREAT;
|
||||
#endif
|
||||
|
||||
state->crs_lock_fd = open(state->crs_lock_file, openflags, 0600); /* flawfinder: ignore */
|
||||
state->cursor.lock_fd = open(state->cursor.lock_file, openflags, 0600); /* flawfinder: ignore */
|
||||
|
||||
/*
|
||||
* flawfinder rationale: we aren't truncating the lock file, we
|
||||
@@ -126,9 +126,9 @@ static void pv_crs_open_lockfile(pvstate_t state, int fd)
|
||||
* open() is as safe as we can make it.
|
||||
*/
|
||||
|
||||
if (state->crs_lock_fd < 0) {
|
||||
pv_error(state, "%s: %s: %s", state->crs_lock_file, _("failed to open lock file"), strerror(errno));
|
||||
state->cursor = 0;
|
||||
if (state->cursor.lock_fd < 0) {
|
||||
pv_error(state, "%s: %s: %s", state->cursor.lock_file, _("failed to open lock file"), strerror(errno));
|
||||
state->control.cursor = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -144,8 +144,8 @@ static void pv_crs_lock(pvstate_t state, int fd)
|
||||
int lock_fd;
|
||||
|
||||
lock_fd = fd;
|
||||
if (state->crs_lock_fd >= 0)
|
||||
lock_fd = state->crs_lock_fd;
|
||||
if (state->cursor.lock_fd >= 0)
|
||||
lock_fd = state->cursor.lock_fd;
|
||||
|
||||
memset(&lock, 0, sizeof(lock));
|
||||
lock.l_type = (short) F_WRLCK;
|
||||
@@ -154,10 +154,10 @@ static void pv_crs_lock(pvstate_t state, int fd)
|
||||
lock.l_len = 1;
|
||||
while (fcntl(lock_fd, F_SETLKW, &lock) < 0) {
|
||||
if (errno != EINTR) {
|
||||
if (state->crs_lock_fd == -2) {
|
||||
if (state->cursor.lock_fd == -2) {
|
||||
pv_crs_open_lockfile(state, fd);
|
||||
if (state->crs_lock_fd >= 0) {
|
||||
lock_fd = state->crs_lock_fd;
|
||||
if (state->cursor.lock_fd >= 0) {
|
||||
lock_fd = state->cursor.lock_fd;
|
||||
}
|
||||
} else {
|
||||
pv_error(state, "%s: %s", _("lock attempt failed"), strerror(errno));
|
||||
@@ -166,8 +166,8 @@ static void pv_crs_lock(pvstate_t state, int fd)
|
||||
}
|
||||
}
|
||||
|
||||
if (state->crs_lock_fd >= 0) {
|
||||
debug("%s: %s", state->crs_lock_file, "terminal lockfile acquired");
|
||||
if (state->cursor.lock_fd >= 0) {
|
||||
debug("%s: %s", state->cursor.lock_file, "terminal lockfile acquired");
|
||||
} else {
|
||||
debug("%s", "terminal lock acquired");
|
||||
}
|
||||
@@ -184,8 +184,8 @@ static void pv_crs_unlock(pvstate_t state, int fd)
|
||||
int lock_fd;
|
||||
|
||||
lock_fd = fd;
|
||||
if (state->crs_lock_fd >= 0)
|
||||
lock_fd = state->crs_lock_fd;
|
||||
if (state->cursor.lock_fd >= 0)
|
||||
lock_fd = state->cursor.lock_fd;
|
||||
|
||||
memset(&lock, 0, sizeof(lock));
|
||||
lock.l_type = (short) F_UNLCK;
|
||||
@@ -194,8 +194,8 @@ static void pv_crs_unlock(pvstate_t state, int fd)
|
||||
lock.l_len = 1;
|
||||
(void) fcntl(lock_fd, F_SETLK, &lock);
|
||||
|
||||
if (state->crs_lock_fd >= 0) {
|
||||
debug("%s: %s", state->crs_lock_file, "terminal lockfile released");
|
||||
if (state->cursor.lock_fd >= 0) {
|
||||
debug("%s: %s", state->cursor.lock_file, "terminal lockfile released");
|
||||
} else {
|
||||
debug("%s", "terminal lock released");
|
||||
}
|
||||
@@ -216,13 +216,13 @@ static void pv_crs_ipccount(pvstate_t state)
|
||||
memset(&buf, 0, sizeof(buf));
|
||||
buf.shm_nattch = 0;
|
||||
|
||||
(void) shmctl(state->crs_shmid, IPC_STAT, &buf);
|
||||
state->crs_pvcount = (int) (buf.shm_nattch);
|
||||
(void) shmctl(state->cursor.shmid, IPC_STAT, &buf);
|
||||
state->cursor.pvcount = (int) (buf.shm_nattch);
|
||||
|
||||
if (state->crs_pvcount > state->crs_pvmax)
|
||||
state->crs_pvmax = state->crs_pvcount;
|
||||
if (state->cursor.pvcount > state->cursor.pvmax)
|
||||
state->cursor.pvmax = state->cursor.pvcount;
|
||||
|
||||
debug("%s: %d", "pvcount", state->crs_pvcount);
|
||||
debug("%s: %d", "pvcount", state->cursor.pvcount);
|
||||
}
|
||||
#endif /* HAVE_IPC */
|
||||
|
||||
@@ -334,13 +334,13 @@ static int pv_crs_ipcinit(pvstate_t state, char *ttyfile, int terminalfd)
|
||||
}
|
||||
|
||||
pv_crs_lock(state, terminalfd);
|
||||
if (!state->cursor) {
|
||||
if (!state->control.cursor) {
|
||||
debug("%s", "early return - cursor has been disabled");
|
||||
return 1;
|
||||
}
|
||||
|
||||
state->crs_shmid = shmget(key, sizeof(struct pvcursorstate_s), 0600 | IPC_CREAT);
|
||||
if (state->crs_shmid < 0) {
|
||||
state->cursor.shmid = shmget(key, sizeof(struct pvcursorstate_s), 0600 | IPC_CREAT);
|
||||
if (state->cursor.shmid < 0) {
|
||||
debug("%s: %s", "shmget failed", strerror(errno));
|
||||
pv_crs_unlock(state, terminalfd);
|
||||
return 1;
|
||||
@@ -348,7 +348,7 @@ static int pv_crs_ipcinit(pvstate_t state, char *ttyfile, int terminalfd)
|
||||
|
||||
/*@-nullpass@ */
|
||||
/* splint doesn't know shmaddr can be NULL */
|
||||
state->crs_shared = shmat(state->crs_shmid, NULL, 0);
|
||||
state->cursor.shared = shmat(state->cursor.shmid, NULL, 0);
|
||||
/*@+nullpass@ */
|
||||
|
||||
pv_crs_ipccount(state);
|
||||
@@ -359,26 +359,26 @@ static int pv_crs_ipcinit(pvstate_t state, char *ttyfile, int terminalfd)
|
||||
* current Y cursor co-ordinate and with an initial false value for
|
||||
* the TOSTOP-added flag.
|
||||
*/
|
||||
if (state->crs_pvcount < 2) {
|
||||
state->crs_y_start = pv_crs_get_ypos(terminalfd);
|
||||
state->crs_shared->y_topmost = state->crs_y_start;
|
||||
state->crs_shared->tty_tostop_added = false;
|
||||
state->crs_y_lastread = state->crs_y_start;
|
||||
if (state->cursor.pvcount < 2) {
|
||||
state->cursor.y_start = pv_crs_get_ypos(terminalfd);
|
||||
state->cursor.shared->y_topmost = state->cursor.y_start;
|
||||
state->cursor.shared->tty_tostop_added = false;
|
||||
state->cursor.y_lastread = state->cursor.y_start;
|
||||
debug("%s", "we are the first to attach");
|
||||
}
|
||||
|
||||
state->crs_y_offset = state->crs_pvcount - 1;
|
||||
if (state->crs_y_offset < 0)
|
||||
state->crs_y_offset = 0;
|
||||
state->cursor.y_offset = state->cursor.pvcount - 1;
|
||||
if (state->cursor.y_offset < 0)
|
||||
state->cursor.y_offset = 0;
|
||||
|
||||
/*
|
||||
* If anyone else had attached to the shared memory segment, we need
|
||||
* to read the top Y co-ordinate from it.
|
||||
*/
|
||||
if (state->crs_pvcount > 1) {
|
||||
state->crs_y_start = state->crs_shared->y_topmost;
|
||||
state->crs_y_lastread = state->crs_y_start;
|
||||
debug("%s: %d", "not the first to attach - got top y", state->crs_y_start);
|
||||
if (state->cursor.pvcount > 1) {
|
||||
state->cursor.y_start = state->cursor.shared->y_topmost;
|
||||
state->cursor.y_lastread = state->cursor.y_start;
|
||||
debug("%s: %d", "not the first to attach - got top y", state->cursor.y_start);
|
||||
}
|
||||
|
||||
pv_crs_unlock(state, terminalfd);
|
||||
@@ -396,10 +396,10 @@ void pv_crs_init(pvstate_t state)
|
||||
char *ttyfile;
|
||||
int terminalfd;
|
||||
|
||||
state->crs_lock_fd = -2;
|
||||
state->crs_lock_file[0] = '\0';
|
||||
state->cursor.lock_fd = -2;
|
||||
state->cursor.lock_file[0] = '\0';
|
||||
|
||||
if (!state->cursor)
|
||||
if (!state->control.cursor)
|
||||
return;
|
||||
|
||||
debug("%s", "init");
|
||||
@@ -407,7 +407,7 @@ void pv_crs_init(pvstate_t state)
|
||||
ttyfile = ttyname(STDERR_FILENO);
|
||||
if (NULL == ttyfile) {
|
||||
debug("%s: %s", "disabling cursor positioning because ttyname failed", strerror(errno));
|
||||
state->cursor = false;
|
||||
state->control.cursor = false;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -422,22 +422,22 @@ void pv_crs_init(pvstate_t state)
|
||||
|
||||
if (terminalfd < 0) {
|
||||
pv_error(state, "%s: %s: %s", _("failed to open terminal"), ttyfile, strerror(errno));
|
||||
state->cursor = false;
|
||||
state->control.cursor = false;
|
||||
return;
|
||||
}
|
||||
#ifdef HAVE_IPC
|
||||
if (pv_crs_ipcinit(state, ttyfile, terminalfd) != 0) {
|
||||
debug("%s", "ipcinit failed, setting noipc flag");
|
||||
state->crs_noipc = true;
|
||||
state->cursor.noipc = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we have already set the terminal TOSTOP attribute, set the
|
||||
* flag in shared memory to let the other instances know.
|
||||
*/
|
||||
if ((!state->crs_noipc) && state->pv_tty_tostop_added && (NULL != state->crs_shared)) {
|
||||
if ((!state->cursor.noipc) && state->signal.pv_tty_tostop_added && (NULL != state->cursor.shared)) {
|
||||
debug("%s", "propagating local pv_tty_tostop_added true value to shared flag");
|
||||
state->crs_shared->tty_tostop_added = true;
|
||||
state->cursor.shared->tty_tostop_added = true;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -445,7 +445,7 @@ void pv_crs_init(pvstate_t state)
|
||||
* co-ordinate. If we are using IPC, then the pv_crs_ipcinit()
|
||||
* function takes care of this in a more multi-process-friendly way.
|
||||
*/
|
||||
if (state->crs_noipc) {
|
||||
if (state->cursor.noipc) {
|
||||
#else /* ! HAVE_IPC */
|
||||
if (1) {
|
||||
#endif /* HAVE_IPC */
|
||||
@@ -453,18 +453,18 @@ void pv_crs_init(pvstate_t state)
|
||||
* Get current cursor position + 1.
|
||||
*/
|
||||
pv_crs_lock(state, terminalfd);
|
||||
state->crs_y_start = pv_crs_get_ypos(terminalfd);
|
||||
state->cursor.y_start = pv_crs_get_ypos(terminalfd);
|
||||
/*
|
||||
* Move down a line while the terminal is locked, so that
|
||||
* other processes in the pipeline will get a different
|
||||
* initial ypos.
|
||||
*/
|
||||
if (state->crs_y_start > 0)
|
||||
if (state->cursor.y_start > 0)
|
||||
pv_write_retry(STDERR_FILENO, "\n", 1);
|
||||
pv_crs_unlock(state, terminalfd);
|
||||
|
||||
if (state->crs_y_start < 1)
|
||||
state->cursor = 0;
|
||||
if (state->cursor.y_start < 1)
|
||||
state->control.cursor = 0;
|
||||
}
|
||||
|
||||
(void) close(terminalfd);
|
||||
@@ -477,9 +477,9 @@ void pv_crs_init(pvstate_t state)
|
||||
*/
|
||||
void pv_crs_needreinit(pvstate_t state)
|
||||
{
|
||||
state->crs_needreinit += 2;
|
||||
if (state->crs_needreinit > 3)
|
||||
state->crs_needreinit = 3;
|
||||
state->cursor.needreinit += 2;
|
||||
if (state->cursor.needreinit > 3)
|
||||
state->cursor.needreinit = 3;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -495,23 +495,23 @@ static void pv_crs_reinit(pvstate_t state)
|
||||
|
||||
pv_crs_lock(state, STDERR_FILENO);
|
||||
|
||||
state->crs_needreinit--;
|
||||
if (state->crs_y_offset < 1)
|
||||
state->crs_needreinit = 0;
|
||||
state->cursor.needreinit--;
|
||||
if (state->cursor.y_offset < 1)
|
||||
state->cursor.needreinit = 0;
|
||||
|
||||
if (state->crs_needreinit > 0) {
|
||||
if (state->cursor.needreinit > 0) {
|
||||
pv_crs_unlock(state, STDERR_FILENO);
|
||||
return;
|
||||
}
|
||||
|
||||
debug("%s", "reinit full");
|
||||
|
||||
state->crs_y_start = pv_crs_get_ypos(STDERR_FILENO);
|
||||
state->cursor.y_start = pv_crs_get_ypos(STDERR_FILENO);
|
||||
|
||||
if ((state->crs_y_offset < 1) && (NULL != state->crs_shared)) {
|
||||
state->crs_shared->y_topmost = state->crs_y_start;
|
||||
if ((state->cursor.y_offset < 1) && (NULL != state->cursor.shared)) {
|
||||
state->cursor.shared->y_topmost = state->cursor.y_start;
|
||||
}
|
||||
state->crs_y_lastread = state->crs_y_start;
|
||||
state->cursor.y_lastread = state->cursor.y_start;
|
||||
|
||||
pv_crs_unlock(state, STDERR_FILENO);
|
||||
}
|
||||
@@ -539,24 +539,24 @@ void pv_crs_update(pvstate_t state, const char *output_line)
|
||||
/* flawfinder - output_line is explictly expected to be \0-terminated. */
|
||||
|
||||
#ifdef HAVE_IPC
|
||||
if (!state->crs_noipc) {
|
||||
if (state->crs_needreinit > 0)
|
||||
if (!state->cursor.noipc) {
|
||||
if (state->cursor.needreinit > 0)
|
||||
pv_crs_reinit(state);
|
||||
|
||||
pv_crs_ipccount(state);
|
||||
if (NULL != state->crs_shared) {
|
||||
if (state->crs_y_lastread != state->crs_shared->y_topmost) {
|
||||
state->crs_y_start = state->crs_shared->y_topmost;
|
||||
state->crs_y_lastread = state->crs_y_start;
|
||||
if (NULL != state->cursor.shared) {
|
||||
if (state->cursor.y_lastread != state->cursor.shared->y_topmost) {
|
||||
state->cursor.y_start = state->cursor.shared->y_topmost;
|
||||
state->cursor.y_lastread = state->cursor.y_start;
|
||||
}
|
||||
}
|
||||
|
||||
if (state->crs_needreinit > 0)
|
||||
if (state->cursor.needreinit > 0)
|
||||
return;
|
||||
}
|
||||
#endif /* HAVE_IPC */
|
||||
|
||||
y = state->crs_y_start;
|
||||
y = state->cursor.y_start;
|
||||
|
||||
#ifdef HAVE_IPC
|
||||
/*
|
||||
@@ -565,27 +565,27 @@ void pv_crs_update(pvstate_t state, const char *output_line)
|
||||
* scroll the screen (only if we're the first `pv'), and then move
|
||||
* our initial Y co-ordinate up.
|
||||
*/
|
||||
if (((state->crs_y_start + state->crs_pvmax) > (int) (state->height))
|
||||
&& (!state->crs_noipc)
|
||||
if (((state->cursor.y_start + state->cursor.pvmax) > (int) (state->control.height))
|
||||
&& (!state->cursor.noipc)
|
||||
) {
|
||||
int offs;
|
||||
|
||||
offs = ((state->crs_y_start + state->crs_pvmax) - state->height);
|
||||
offs = ((state->cursor.y_start + state->cursor.pvmax) - state->control.height);
|
||||
|
||||
state->crs_y_start -= offs;
|
||||
if (state->crs_y_start < 1)
|
||||
state->crs_y_start = 1;
|
||||
state->cursor.y_start -= offs;
|
||||
if (state->cursor.y_start < 1)
|
||||
state->cursor.y_start = 1;
|
||||
|
||||
debug("%s: %d", "scroll offset", offs);
|
||||
|
||||
/*
|
||||
* Scroll the screen if we're the first `pv'.
|
||||
*/
|
||||
if (0 == state->crs_y_offset) {
|
||||
if (0 == state->cursor.y_offset) {
|
||||
pv_crs_lock(state, STDERR_FILENO);
|
||||
|
||||
memset(cup_cmd, 0, sizeof(cup_cmd));
|
||||
(void) pv_snprintf(cup_cmd, sizeof(cup_cmd), "\033[%u;1H", state->height);
|
||||
(void) pv_snprintf(cup_cmd, sizeof(cup_cmd), "\033[%u;1H", state->control.height);
|
||||
cup_cmd_length = strlen(cup_cmd); /* flawfinder: ignore */
|
||||
pv_write_retry(STDERR_FILENO, cup_cmd, cup_cmd_length);
|
||||
for (; offs > 0; offs--) {
|
||||
@@ -598,8 +598,8 @@ void pv_crs_update(pvstate_t state, const char *output_line)
|
||||
}
|
||||
}
|
||||
|
||||
if (!state->crs_noipc)
|
||||
y = state->crs_y_start + state->crs_y_offset;
|
||||
if (!state->cursor.noipc)
|
||||
y = state->cursor.y_start + state->cursor.y_offset;
|
||||
#endif /* HAVE_IPC */
|
||||
|
||||
/*
|
||||
@@ -641,15 +641,15 @@ void pv_crs_fini(pvstate_t state)
|
||||
|
||||
debug("%s", "fini");
|
||||
|
||||
y = (unsigned int) (state->crs_y_start);
|
||||
y = (unsigned int) (state->cursor.y_start);
|
||||
|
||||
#ifdef HAVE_IPC
|
||||
if ((state->crs_pvmax > 0) && (!state->crs_noipc))
|
||||
y += state->crs_pvmax - 1;
|
||||
if ((state->cursor.pvmax > 0) && (!state->cursor.noipc))
|
||||
y += state->cursor.pvmax - 1;
|
||||
#endif /* HAVE_IPC */
|
||||
|
||||
if (y > state->height)
|
||||
y = state->height;
|
||||
if (y > state->control.height)
|
||||
y = state->control.height;
|
||||
|
||||
/*
|
||||
* Absolute bounds check.
|
||||
@@ -671,40 +671,40 @@ void pv_crs_fini(pvstate_t state)
|
||||
* attribute, set our local flag so pv_sig_fini() will know about
|
||||
* it.
|
||||
*/
|
||||
if ((!state->crs_noipc) && (NULL != state->crs_shared) && state->crs_shared->tty_tostop_added) {
|
||||
if (!state->pv_tty_tostop_added) {
|
||||
if ((!state->cursor.noipc) && (NULL != state->cursor.shared) && state->cursor.shared->tty_tostop_added) {
|
||||
if (!state->signal.pv_tty_tostop_added) {
|
||||
debug("%s", "propagating shared tty_tostop_added true value to local flag");
|
||||
state->pv_tty_tostop_added = true;
|
||||
state->signal.pv_tty_tostop_added = true;
|
||||
}
|
||||
}
|
||||
|
||||
pv_crs_ipccount(state);
|
||||
if (NULL != state->crs_shared) {
|
||||
(void) shmdt(state->crs_shared);
|
||||
if (NULL != state->cursor.shared) {
|
||||
(void) shmdt(state->cursor.shared);
|
||||
}
|
||||
state->crs_shared = NULL;
|
||||
state->cursor.shared = NULL;
|
||||
|
||||
/*
|
||||
* If we are the last instance detaching from the shared memory,
|
||||
* delete it so it's not left lying around.
|
||||
*/
|
||||
if (state->crs_pvcount < 2) {
|
||||
if (state->cursor.pvcount < 2) {
|
||||
struct shmid_ds shm_buf;
|
||||
memset(&shm_buf, 0, sizeof(shm_buf));
|
||||
(void) shmctl(state->crs_shmid, IPC_RMID, &shm_buf);
|
||||
(void) shmctl(state->cursor.shmid, IPC_RMID, &shm_buf);
|
||||
}
|
||||
|
||||
#endif /* HAVE_IPC */
|
||||
|
||||
pv_crs_unlock(state, STDERR_FILENO);
|
||||
|
||||
if (state->crs_lock_fd >= 0) {
|
||||
(void) close(state->crs_lock_fd);
|
||||
if (state->cursor.lock_fd >= 0) {
|
||||
(void) close(state->cursor.lock_fd);
|
||||
/*
|
||||
* We can get away with removing this on exit because all
|
||||
* the other PVs will be finishing at the same sort of time.
|
||||
*/
|
||||
(void) remove(state->crs_lock_file);
|
||||
(void) remove(state->cursor.lock_file);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+225
-220
@@ -42,9 +42,9 @@
|
||||
void pv_error(pvstate_t state, char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
if (state->display_visible)
|
||||
if (state->display.display_visible)
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "%s: ", state->program_name);
|
||||
fprintf(stderr, "%s: ", state->status.program_name);
|
||||
va_start(ap, format);
|
||||
(void) vfprintf(stderr, format, ap);
|
||||
va_end(ap);
|
||||
@@ -374,22 +374,22 @@ static void pv__format_init(pvstate_t state)
|
||||
if (NULL == state)
|
||||
return;
|
||||
|
||||
state->str_name[0] = '\0';
|
||||
state->str_transferred[0] = '\0';
|
||||
state->str_timer[0] = '\0';
|
||||
state->str_rate[0] = '\0';
|
||||
state->str_average_rate[0] = '\0';
|
||||
state->str_progress[0] = '\0';
|
||||
state->str_eta[0] = '\0';
|
||||
memset(state->format, 0, PV_FORMAT_ARRAY_MAX * sizeof(state->format[0]));
|
||||
state->display.str_name[0] = '\0';
|
||||
state->display.str_transferred[0] = '\0';
|
||||
state->display.str_timer[0] = '\0';
|
||||
state->display.str_rate[0] = '\0';
|
||||
state->display.str_average_rate[0] = '\0';
|
||||
state->display.str_progress[0] = '\0';
|
||||
state->display.str_eta[0] = '\0';
|
||||
memset(state->display.format, 0, PV_FORMAT_ARRAY_MAX * sizeof(state->display.format[0]));
|
||||
|
||||
if (state->name) {
|
||||
(void) pv_snprintf(state->str_name, PV_SIZEOF_STR_NAME, "%9.500s:", state->name);
|
||||
if (state->control.name) {
|
||||
(void) pv_snprintf(state->display.str_name, PV_SIZEOF_STR_NAME, "%9.500s:", state->control.name);
|
||||
}
|
||||
|
||||
formatstr = state->format_string ? state->format_string : state->default_format;
|
||||
formatstr = state->control.format_string ? state->control.format_string : state->control.default_format;
|
||||
|
||||
state->components_used = 0;
|
||||
state->display.components_used = 0;
|
||||
|
||||
/*
|
||||
* Split the format string into segments. Each segment consists
|
||||
@@ -403,7 +403,7 @@ static void pv__format_init(pvstate_t state)
|
||||
* sized component which will be recalculated by pv__format()
|
||||
* after the length of all fixed-size segments is known, and so
|
||||
* the string is a pointer to another state->str_* buffer
|
||||
* (currently it will only ever be state->str_progress).
|
||||
* (currently it will only ever be state->display.str_progress).
|
||||
*
|
||||
* A length above zero indicates that the segment is a constant
|
||||
* string of the given length (not necessarily null terminated).
|
||||
@@ -443,74 +443,74 @@ static void pv__format_init(pvstate_t state)
|
||||
|
||||
switch (formatstr[strpos]) {
|
||||
case 'p':
|
||||
state->format[segment].string = state->str_progress;
|
||||
state->format[segment].length = -1;
|
||||
state->components_used |= PV_DISPLAY_PROGRESS;
|
||||
state->display.format[segment].string = state->display.str_progress;
|
||||
state->display.format[segment].length = -1;
|
||||
state->display.components_used |= PV_DISPLAY_PROGRESS;
|
||||
break;
|
||||
case 't':
|
||||
state->format[segment].string = state->str_timer;
|
||||
state->format[segment].length = 0;
|
||||
state->components_used |= PV_DISPLAY_TIMER;
|
||||
state->display.format[segment].string = state->display.str_timer;
|
||||
state->display.format[segment].length = 0;
|
||||
state->display.components_used |= PV_DISPLAY_TIMER;
|
||||
break;
|
||||
case 'e':
|
||||
state->format[segment].string = state->str_eta;
|
||||
state->format[segment].length = 0;
|
||||
state->components_used |= PV_DISPLAY_ETA;
|
||||
state->display.format[segment].string = state->display.str_eta;
|
||||
state->display.format[segment].length = 0;
|
||||
state->display.components_used |= PV_DISPLAY_ETA;
|
||||
break;
|
||||
case 'I':
|
||||
state->format[segment].string = state->str_fineta;
|
||||
state->format[segment].length = 0;
|
||||
state->components_used |= PV_DISPLAY_FINETA;
|
||||
state->display.format[segment].string = state->display.str_fineta;
|
||||
state->display.format[segment].length = 0;
|
||||
state->display.components_used |= PV_DISPLAY_FINETA;
|
||||
break;
|
||||
case 'A':
|
||||
state->format[segment].string = state->str_lastoutput;
|
||||
state->format[segment].length = 0;
|
||||
state->display.format[segment].string = state->display.str_lastoutput;
|
||||
state->display.format[segment].length = 0;
|
||||
if (number_prefix > PV_SIZEOF_LASTOUTPUT_BUFFER)
|
||||
number_prefix = PV_SIZEOF_LASTOUTPUT_BUFFER;
|
||||
if (number_prefix < 1)
|
||||
number_prefix = 1;
|
||||
state->lastoutput_length = number_prefix;
|
||||
state->components_used |= PV_DISPLAY_OUTPUTBUF;
|
||||
state->display.lastoutput_length = number_prefix;
|
||||
state->display.components_used |= PV_DISPLAY_OUTPUTBUF;
|
||||
break;
|
||||
case 'r':
|
||||
state->format[segment].string = state->str_rate;
|
||||
state->format[segment].length = 0;
|
||||
state->components_used |= PV_DISPLAY_RATE;
|
||||
state->display.format[segment].string = state->display.str_rate;
|
||||
state->display.format[segment].length = 0;
|
||||
state->display.components_used |= PV_DISPLAY_RATE;
|
||||
break;
|
||||
case 'a':
|
||||
state->format[segment].string = state->str_average_rate;
|
||||
state->format[segment].length = 0;
|
||||
state->components_used |= PV_DISPLAY_AVERAGERATE;
|
||||
state->display.format[segment].string = state->display.str_average_rate;
|
||||
state->display.format[segment].length = 0;
|
||||
state->display.components_used |= PV_DISPLAY_AVERAGERATE;
|
||||
break;
|
||||
case 'b':
|
||||
state->format[segment].string = state->str_transferred;
|
||||
state->format[segment].length = 0;
|
||||
state->components_used |= PV_DISPLAY_BYTES;
|
||||
state->display.format[segment].string = state->display.str_transferred;
|
||||
state->display.format[segment].length = 0;
|
||||
state->display.components_used |= PV_DISPLAY_BYTES;
|
||||
break;
|
||||
case 'T':
|
||||
state->format[segment].string = state->str_bufpercent;
|
||||
state->format[segment].length = 0;
|
||||
state->components_used |= PV_DISPLAY_BUFPERCENT;
|
||||
state->display.format[segment].string = state->display.str_bufpercent;
|
||||
state->display.format[segment].length = 0;
|
||||
state->display.components_used |= PV_DISPLAY_BUFPERCENT;
|
||||
break;
|
||||
case 'N':
|
||||
state->format[segment].string = state->str_name;
|
||||
state->format[segment].length = (int) strlen(state->str_name);
|
||||
state->components_used |= PV_DISPLAY_NAME;
|
||||
state->display.format[segment].string = state->display.str_name;
|
||||
state->display.format[segment].length = (int) strlen(state->display.str_name);
|
||||
state->display.components_used |= PV_DISPLAY_NAME;
|
||||
break;
|
||||
case '%':
|
||||
/* %% => % */
|
||||
state->format[segment].string = &(formatstr[strpos]);
|
||||
state->format[segment].length = 1;
|
||||
state->display.format[segment].string = &(formatstr[strpos]);
|
||||
state->display.format[segment].length = 1;
|
||||
break;
|
||||
case 0:
|
||||
/* % at end => just % */
|
||||
state->format[segment].string = &(formatstr[--strpos]);
|
||||
state->format[segment].length = 1;
|
||||
state->display.format[segment].string = &(formatstr[--strpos]);
|
||||
state->display.format[segment].length = 1;
|
||||
break;
|
||||
default:
|
||||
/* %z (unknown) => %z */
|
||||
state->format[segment].string = &(formatstr[--strpos]);
|
||||
state->format[segment].length = 2;
|
||||
state->display.format[segment].string = &(formatstr[--strpos]);
|
||||
state->display.format[segment].length = 2;
|
||||
strpos++;
|
||||
break;
|
||||
}
|
||||
@@ -522,14 +522,14 @@ static void pv__format_init(pvstate_t state)
|
||||
} else {
|
||||
foundlength = searchptr - &(formatstr[strpos]);
|
||||
}
|
||||
state->format[segment].string = &(formatstr[strpos]);
|
||||
state->format[segment].length = foundlength;
|
||||
state->display.format[segment].string = &(formatstr[strpos]);
|
||||
state->display.format[segment].length = foundlength;
|
||||
strpos += foundlength - 1;
|
||||
}
|
||||
}
|
||||
|
||||
state->format[segment].string = 0;
|
||||
state->format[segment].length = 0;
|
||||
state->display.format[segment].string = 0;
|
||||
state->display.format[segment].length = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -544,21 +544,21 @@ static long bound_long(long x, long min, long max)
|
||||
/* Update history and current average rate */
|
||||
static void update_history_avg_rate(pvstate_t state, long long total_bytes, long double elapsed_sec, long double rate)
|
||||
{
|
||||
int first = state->history_first;
|
||||
int last = state->history_last;
|
||||
int first = state->display.history_first;
|
||||
int last = state->display.history_last;
|
||||
long double last_elapsed;
|
||||
|
||||
if (NULL == state->history)
|
||||
if (NULL == state->display.history)
|
||||
return;
|
||||
|
||||
last_elapsed = state->history[last].elapsed_sec;
|
||||
last_elapsed = state->display.history[last].elapsed_sec;
|
||||
|
||||
/*
|
||||
* Do nothing if this is not the first call but not enough time has
|
||||
* elapsed since the previous call yet.
|
||||
*/
|
||||
if ((last_elapsed > 0.0)
|
||||
&& (elapsed_sec < (last_elapsed + state->history_interval)))
|
||||
&& (elapsed_sec < (last_elapsed + state->display.history_interval)))
|
||||
return;
|
||||
|
||||
/*
|
||||
@@ -566,21 +566,23 @@ static void update_history_avg_rate(pvstate_t state, long long total_bytes, long
|
||||
* buffer.
|
||||
*/
|
||||
if (last_elapsed > 0.0) {
|
||||
int len = state->history_len;
|
||||
state->history_last = last = (last + 1) % len;
|
||||
int len = state->display.history_len;
|
||||
state->display.history_last = last = (last + 1) % len;
|
||||
if (last == first)
|
||||
state->history_first = first = (first + 1) % len;
|
||||
state->display.history_first = first = (first + 1) % len;
|
||||
}
|
||||
|
||||
state->history[last].elapsed_sec = elapsed_sec;
|
||||
state->history[last].total_bytes = total_bytes;
|
||||
state->display.history[last].elapsed_sec = elapsed_sec;
|
||||
state->display.history[last].total_bytes = total_bytes;
|
||||
|
||||
if (first == last) {
|
||||
state->current_avg_rate = rate;
|
||||
state->display.current_avg_rate = rate;
|
||||
} else {
|
||||
long long bytes = (state->history[last].total_bytes - state->history[first].total_bytes);
|
||||
long double sec = (state->history[last].elapsed_sec - state->history[first].elapsed_sec);
|
||||
state->current_avg_rate = (long double) bytes / sec;
|
||||
long long bytes =
|
||||
(state->display.history[last].total_bytes - state->display.history[first].total_bytes);
|
||||
long double sec =
|
||||
(state->display.history[last].elapsed_sec - state->display.history[first].elapsed_sec);
|
||||
state->display.current_avg_rate = (long double) bytes / sec;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -617,9 +619,9 @@ static const char *pv__format(pvstate_t state,
|
||||
|
||||
/* Negative total transfer - free memory and exit */
|
||||
if (total_bytes < 0) {
|
||||
if (state->display_buffer)
|
||||
free(state->display_buffer);
|
||||
state->display_buffer = NULL;
|
||||
if (state->display.display_buffer)
|
||||
free(state->display.display_buffer);
|
||||
state->display.display_buffer = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -629,20 +631,20 @@ static const char *pv__format(pvstate_t state,
|
||||
* adding to that until a reasonable amount of time has passed to
|
||||
* avoid rate spikes or division by zero.
|
||||
*/
|
||||
time_since_last = elapsed_sec - state->prev_elapsed_sec;
|
||||
time_since_last = elapsed_sec - state->display.prev_elapsed_sec;
|
||||
if (time_since_last <= 0.01) {
|
||||
rate = state->prev_rate;
|
||||
state->prev_trans += bytes_since_last;
|
||||
rate = state->display.prev_rate;
|
||||
state->display.prev_trans += bytes_since_last;
|
||||
} else {
|
||||
rate = ((long double) bytes_since_last + state->prev_trans) / time_since_last;
|
||||
state->prev_elapsed_sec = elapsed_sec;
|
||||
state->prev_trans = 0;
|
||||
rate = ((long double) bytes_since_last + state->display.prev_trans) / time_since_last;
|
||||
state->display.prev_elapsed_sec = elapsed_sec;
|
||||
state->display.prev_trans = 0;
|
||||
}
|
||||
state->prev_rate = rate;
|
||||
state->display.prev_rate = rate;
|
||||
|
||||
/* Update history and current average rate for ETA. */
|
||||
update_history_avg_rate(state, total_bytes, elapsed_sec, rate);
|
||||
average_rate = state->current_avg_rate;
|
||||
average_rate = state->display.current_avg_rate;
|
||||
|
||||
/*
|
||||
* If this is the final update at the end of the transfer, we
|
||||
@@ -654,11 +656,12 @@ static const char *pv__format(pvstate_t state,
|
||||
if (elapsed_sec < 0.000001)
|
||||
elapsed_sec = 0.000001;
|
||||
average_rate =
|
||||
(((long double) total_bytes) - ((long double) state->initial_offset)) / (long double) elapsed_sec;
|
||||
(((long double) total_bytes) -
|
||||
((long double) state->display.initial_offset)) / (long double) elapsed_sec;
|
||||
rate = average_rate;
|
||||
}
|
||||
|
||||
if (state->size <= 0) {
|
||||
if (state->control.size <= 0) {
|
||||
/*
|
||||
* If we don't know the total size of the incoming data,
|
||||
* then for a percentage, we gradually increase the
|
||||
@@ -668,41 +671,41 @@ static const char *pv__format(pvstate_t state,
|
||||
* 0%-100%, 100%-0%, 0%-100%, and so on.
|
||||
*/
|
||||
if (rate > 0)
|
||||
state->percentage += 2;
|
||||
if (state->percentage > 199)
|
||||
state->percentage = 0;
|
||||
} else if (state->numeric || ((state->components_used & PV_DISPLAY_PROGRESS) != 0)) {
|
||||
state->display.percentage += 2;
|
||||
if (state->display.percentage > 199)
|
||||
state->display.percentage = 0;
|
||||
} else if (state->control.numeric || ((state->display.components_used & PV_DISPLAY_PROGRESS) != 0)) {
|
||||
/*
|
||||
* If we do know the total size, and we're going to show
|
||||
* the percentage (numeric mode or a progress bar),
|
||||
* calculate the percentage completion.
|
||||
*/
|
||||
state->percentage = pv__calc_percentage(total_bytes, state->size);
|
||||
state->display.percentage = pv__calc_percentage(total_bytes, state->control.size);
|
||||
}
|
||||
|
||||
/*
|
||||
* Reallocate output buffer if width changes.
|
||||
*/
|
||||
if (state->display_buffer != NULL && state->display_buffer_size < (state->width * 2)) {
|
||||
free(state->display_buffer);
|
||||
state->display_buffer = NULL;
|
||||
state->display_buffer_size = 0;
|
||||
if (state->display.display_buffer != NULL && state->display.display_buffer_size < (state->control.width * 2)) {
|
||||
free(state->display.display_buffer);
|
||||
state->display.display_buffer = NULL;
|
||||
state->display.display_buffer_size = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate output buffer if there isn't one.
|
||||
*/
|
||||
if (NULL == state->display_buffer) {
|
||||
state->display_buffer_size = (2 * state->width) + 80;
|
||||
if (state->name)
|
||||
state->display_buffer_size += strlen(state->name);
|
||||
state->display_buffer = malloc(state->display_buffer_size + 16);
|
||||
if (NULL == state->display_buffer) {
|
||||
if (NULL == state->display.display_buffer) {
|
||||
state->display.display_buffer_size = (2 * state->control.width) + 80;
|
||||
if (state->control.name)
|
||||
state->display.display_buffer_size += strlen(state->control.name);
|
||||
state->display.display_buffer = malloc(state->display.display_buffer_size + 16);
|
||||
if (NULL == state->display.display_buffer) {
|
||||
pv_error(state, "%s: %s", _("buffer allocation failed"), strerror(errno));
|
||||
state->exit_status |= 64;
|
||||
state->status.exit_status |= 64;
|
||||
return NULL;
|
||||
}
|
||||
state->display_buffer[0] = '\0';
|
||||
state->display.display_buffer[0] = '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -713,30 +716,31 @@ static const char *pv__format(pvstate_t state,
|
||||
* With --bytes we output the bytes transferred so far instead
|
||||
* of the percentage. (Or lines, if --lines was given with --bytes).
|
||||
*/
|
||||
if (state->numeric) {
|
||||
if (state->control.numeric) {
|
||||
char numericprefix[128];
|
||||
|
||||
numericprefix[0] = '\0';
|
||||
|
||||
if ((state->components_used & PV_DISPLAY_TIMER) != 0)
|
||||
if ((state->display.components_used & PV_DISPLAY_TIMER) != 0)
|
||||
(void) pv_snprintf(numericprefix, sizeof(numericprefix), "%.4Lf ", elapsed_sec);
|
||||
|
||||
if ((state->components_used & PV_DISPLAY_BYTES) != 0) {
|
||||
if (state->bits) {
|
||||
(void) pv_snprintf(state->display_buffer,
|
||||
state->display_buffer_size,
|
||||
if ((state->display.components_used & PV_DISPLAY_BYTES) != 0) {
|
||||
if (state->control.bits) {
|
||||
(void) pv_snprintf(state->display.display_buffer,
|
||||
state->display.display_buffer_size,
|
||||
"%.99s%lld\n", numericprefix, 8 * total_bytes);
|
||||
} else {
|
||||
(void) pv_snprintf(state->display_buffer,
|
||||
state->display_buffer_size,
|
||||
(void) pv_snprintf(state->display.display_buffer,
|
||||
state->display.display_buffer_size,
|
||||
"%.99s%lld\n", numericprefix, total_bytes);
|
||||
}
|
||||
} else {
|
||||
(void) pv_snprintf(state->display_buffer,
|
||||
state->display_buffer_size, "%.99s%ld\n", numericprefix, state->percentage);
|
||||
(void) pv_snprintf(state->display.display_buffer,
|
||||
state->display.display_buffer_size, "%.99s%ld\n", numericprefix,
|
||||
state->display.percentage);
|
||||
}
|
||||
|
||||
return state->display_buffer;
|
||||
return state->display.display_buffer;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -746,46 +750,47 @@ static const char *pv__format(pvstate_t state,
|
||||
* to be placed in the output buffer.
|
||||
*/
|
||||
|
||||
state->str_transferred[0] = '\0';
|
||||
state->str_bufpercent[0] = '\0';
|
||||
state->str_timer[0] = '\0';
|
||||
state->str_rate[0] = '\0';
|
||||
state->str_average_rate[0] = '\0';
|
||||
state->str_progress[0] = '\0';
|
||||
state->str_lastoutput[0] = '\0';
|
||||
state->str_eta[0] = '\0';
|
||||
state->str_fineta[0] = '\0';
|
||||
state->display.str_transferred[0] = '\0';
|
||||
state->display.str_bufpercent[0] = '\0';
|
||||
state->display.str_timer[0] = '\0';
|
||||
state->display.str_rate[0] = '\0';
|
||||
state->display.str_average_rate[0] = '\0';
|
||||
state->display.str_progress[0] = '\0';
|
||||
state->display.str_lastoutput[0] = '\0';
|
||||
state->display.str_eta[0] = '\0';
|
||||
state->display.str_fineta[0] = '\0';
|
||||
|
||||
/* If we're showing bytes transferred, set up the display string. */
|
||||
if ((state->components_used & PV_DISPLAY_BYTES) != 0) {
|
||||
if (state->bits && !state->linemode) {
|
||||
pv__sizestr(state->str_transferred,
|
||||
if ((state->display.components_used & PV_DISPLAY_BYTES) != 0) {
|
||||
if (state->control.bits && !state->control.linemode) {
|
||||
pv__sizestr(state->display.str_transferred,
|
||||
PV_SIZEOF_STR_TRANSFERRED, "%s", (long double) total_bytes * 8, "", _("b"),
|
||||
PV_TRANSFERCOUNT_BYTES);
|
||||
} else {
|
||||
pv__sizestr(state->str_transferred,
|
||||
pv__sizestr(state->display.str_transferred,
|
||||
PV_SIZEOF_STR_TRANSFERRED, "%s",
|
||||
(long double) total_bytes, "", _("B"),
|
||||
state->linemode ? PV_TRANSFERCOUNT_LINES : PV_TRANSFERCOUNT_BYTES);
|
||||
state->control.linemode ? PV_TRANSFERCOUNT_LINES : PV_TRANSFERCOUNT_BYTES);
|
||||
}
|
||||
}
|
||||
|
||||
/* Transfer buffer percentage - set up the display string. */
|
||||
if ((state->components_used & PV_DISPLAY_BUFPERCENT) != 0) {
|
||||
if (state->buffer_size > 0)
|
||||
(void) pv_snprintf(state->str_bufpercent,
|
||||
if ((state->display.components_used & PV_DISPLAY_BUFPERCENT) != 0) {
|
||||
if (state->transfer.buffer_size > 0)
|
||||
(void) pv_snprintf(state->display.str_bufpercent,
|
||||
PV_SIZEOF_STR_BUFPERCENT,
|
||||
"{%3ld%%}",
|
||||
pv__calc_percentage
|
||||
(state->read_position - state->write_position, state->buffer_size));
|
||||
(state->transfer.read_position - state->transfer.write_position,
|
||||
state->transfer.buffer_size));
|
||||
#ifdef HAVE_SPLICE
|
||||
if (state->splice_used)
|
||||
(void) pv_snprintf(state->str_bufpercent, PV_SIZEOF_STR_BUFPERCENT, "{%s}", "----");
|
||||
if (state->transfer.splice_used)
|
||||
(void) pv_snprintf(state->display.str_bufpercent, PV_SIZEOF_STR_BUFPERCENT, "{%s}", "----");
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Timer - set up the display string. */
|
||||
if ((state->components_used & PV_DISPLAY_TIMER) != 0) {
|
||||
if ((state->display.components_used & PV_DISPLAY_TIMER) != 0) {
|
||||
/*
|
||||
* Bounds check, so we don't overrun the prefix buffer. This
|
||||
* does mean that the timer will stop at a 100,000 hours,
|
||||
@@ -799,14 +804,14 @@ static const char *pv__format(pvstate_t state,
|
||||
* well as hours, minutes, and seconds.
|
||||
*/
|
||||
if (elapsed_sec > (long double) 86400.0L) {
|
||||
(void) pv_snprintf(state->str_timer,
|
||||
(void) pv_snprintf(state->display.str_timer,
|
||||
PV_SIZEOF_STR_TIMER,
|
||||
"%ld:%02ld:%02ld:%02ld",
|
||||
((long) elapsed_sec) / 86400,
|
||||
(((long) elapsed_sec) / 3600) %
|
||||
24, (((long) elapsed_sec) / 60) % 60, ((long) elapsed_sec) % 60);
|
||||
} else {
|
||||
(void) pv_snprintf(state->str_timer,
|
||||
(void) pv_snprintf(state->display.str_timer,
|
||||
PV_SIZEOF_STR_TIMER,
|
||||
"%ld:%02ld:%02ld",
|
||||
((long) elapsed_sec) / 3600,
|
||||
@@ -815,48 +820,48 @@ static const char *pv__format(pvstate_t state,
|
||||
}
|
||||
|
||||
/* Rate - set up the display string. */
|
||||
if ((state->components_used & PV_DISPLAY_RATE) != 0) {
|
||||
if (state->bits && !state->linemode) {
|
||||
pv__sizestr(state->str_rate, PV_SIZEOF_STR_RATE, "[%s]", 8 * rate, "", _("b/s"),
|
||||
if ((state->display.components_used & PV_DISPLAY_RATE) != 0) {
|
||||
if (state->control.bits && !state->control.linemode) {
|
||||
pv__sizestr(state->display.str_rate, PV_SIZEOF_STR_RATE, "[%s]", 8 * rate, "", _("b/s"),
|
||||
PV_TRANSFERCOUNT_BYTES);
|
||||
} else {
|
||||
pv__sizestr(state->str_rate,
|
||||
pv__sizestr(state->display.str_rate,
|
||||
PV_SIZEOF_STR_RATE, "[%s]", rate, _("/s"), _("B/s"),
|
||||
state->linemode ? PV_TRANSFERCOUNT_LINES : PV_TRANSFERCOUNT_BYTES);
|
||||
state->control.linemode ? PV_TRANSFERCOUNT_LINES : PV_TRANSFERCOUNT_BYTES);
|
||||
}
|
||||
}
|
||||
|
||||
/* Average rate - set up the display string. */
|
||||
if ((state->components_used & PV_DISPLAY_AVERAGERATE) != 0) {
|
||||
if (state->bits && !state->linemode) {
|
||||
pv__sizestr(state->str_average_rate,
|
||||
if ((state->display.components_used & PV_DISPLAY_AVERAGERATE) != 0) {
|
||||
if (state->control.bits && !state->control.linemode) {
|
||||
pv__sizestr(state->display.str_average_rate,
|
||||
PV_SIZEOF_STR_AVERAGE_RATE, "[%s]", 8 * average_rate, "", _("b/s"),
|
||||
PV_TRANSFERCOUNT_BYTES);
|
||||
} else {
|
||||
pv__sizestr(state->str_average_rate,
|
||||
pv__sizestr(state->display.str_average_rate,
|
||||
PV_SIZEOF_STR_AVERAGE_RATE,
|
||||
"[%s]", average_rate, _("/s"), _("B/s"),
|
||||
state->linemode ? PV_TRANSFERCOUNT_LINES : PV_TRANSFERCOUNT_BYTES);
|
||||
state->control.linemode ? PV_TRANSFERCOUNT_LINES : PV_TRANSFERCOUNT_BYTES);
|
||||
}
|
||||
}
|
||||
|
||||
/* Last output bytes - set up the display string. */
|
||||
if ((state->components_used & PV_DISPLAY_OUTPUTBUF) != 0) {
|
||||
if ((state->display.components_used & PV_DISPLAY_OUTPUTBUF) != 0) {
|
||||
int idx;
|
||||
for (idx = 0; idx < state->lastoutput_length; idx++) {
|
||||
for (idx = 0; idx < state->display.lastoutput_length; idx++) {
|
||||
int c;
|
||||
c = state->lastoutput_buffer[idx];
|
||||
state->str_lastoutput[idx] = isprint(c) ? c : '.';
|
||||
c = state->display.lastoutput_buffer[idx];
|
||||
state->display.str_lastoutput[idx] = isprint(c) ? c : '.';
|
||||
}
|
||||
state->str_lastoutput[idx] = '\0';
|
||||
state->display.str_lastoutput[idx] = '\0';
|
||||
}
|
||||
|
||||
/* ETA (only if size is known) - set up the display string. */
|
||||
if (((state->components_used & PV_DISPLAY_ETA) != 0)
|
||||
&& (state->size > 0)) {
|
||||
if (((state->display.components_used & PV_DISPLAY_ETA) != 0)
|
||||
&& (state->control.size > 0)) {
|
||||
eta =
|
||||
pv__calc_eta(total_bytes - state->initial_offset,
|
||||
state->size - state->initial_offset, state->current_avg_rate);
|
||||
pv__calc_eta(total_bytes - state->display.initial_offset,
|
||||
state->control.size - state->display.initial_offset, state->display.current_avg_rate);
|
||||
|
||||
/*
|
||||
* Bounds check, so we don't overrun the suffix buffer. This
|
||||
@@ -869,12 +874,12 @@ static const char *pv__format(pvstate_t state,
|
||||
* well as hours, minutes, and seconds.
|
||||
*/
|
||||
if (eta > 86400L) {
|
||||
(void) pv_snprintf(state->str_eta,
|
||||
(void) pv_snprintf(state->display.str_eta,
|
||||
PV_SIZEOF_STR_ETA,
|
||||
"%.16s %ld:%02ld:%02ld:%02ld",
|
||||
_("ETA"), eta / 86400, (eta / 3600) % 24, (eta / 60) % 60, eta % 60);
|
||||
} else {
|
||||
(void) pv_snprintf(state->str_eta,
|
||||
(void) pv_snprintf(state->display.str_eta,
|
||||
PV_SIZEOF_STR_ETA,
|
||||
"%.16s %ld:%02ld:%02ld", _("ETA"), eta / 3600, (eta / 60) % 60, eta % 60);
|
||||
}
|
||||
@@ -885,15 +890,15 @@ static const char *pv__format(pvstate_t state,
|
||||
*/
|
||||
if (bytes_since_last < 0) {
|
||||
unsigned int i;
|
||||
for (i = 0; i < PV_SIZEOF_STR_ETA && state->str_eta[i] != '\0'; i++) {
|
||||
state->str_eta[i] = ' ';
|
||||
for (i = 0; i < PV_SIZEOF_STR_ETA && state->display.str_eta[i] != '\0'; i++) {
|
||||
state->display.str_eta[i] = ' ';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ETA as clock time (as above) - set up the display string. */
|
||||
if (((state->components_used & PV_DISPLAY_FINETA) != 0)
|
||||
&& (state->size > 0)) {
|
||||
if (((state->display.components_used & PV_DISPLAY_FINETA) != 0)
|
||||
&& (state->control.size > 0)) {
|
||||
/*
|
||||
* The ETA may be hidden by a failed ETA string
|
||||
* generation.
|
||||
@@ -905,8 +910,8 @@ static const char *pv__format(pvstate_t state,
|
||||
char *time_format = NULL;
|
||||
|
||||
eta =
|
||||
pv__calc_eta(total_bytes - state->initial_offset,
|
||||
state->size - state->initial_offset, state->current_avg_rate);
|
||||
pv__calc_eta(total_bytes - state->display.initial_offset,
|
||||
state->control.size - state->display.initial_offset, state->display.current_avg_rate);
|
||||
|
||||
/*
|
||||
* Bounds check, so we don't overrun the suffix buffer. This
|
||||
@@ -935,16 +940,16 @@ static const char *pv__format(pvstate_t state,
|
||||
* by time functions. */
|
||||
struct tm time = *time_ptr;
|
||||
|
||||
(void) pv_snprintf(state->str_fineta, PV_SIZEOF_STR_FINETA, "%.16s ", _("ETA"));
|
||||
strftime(state->str_fineta +
|
||||
strlen(state->str_fineta),
|
||||
PV_SIZEOF_STR_FINETA - 1 - strlen(state->str_fineta), time_format, &time);
|
||||
(void) pv_snprintf(state->display.str_fineta, PV_SIZEOF_STR_FINETA, "%.16s ", _("ETA"));
|
||||
strftime(state->display.str_fineta +
|
||||
strlen(state->display.str_fineta),
|
||||
PV_SIZEOF_STR_FINETA - 1 - strlen(state->display.str_fineta), time_format, &time);
|
||||
}
|
||||
|
||||
if (!show_eta) {
|
||||
unsigned int i;
|
||||
for (i = 0; i < PV_SIZEOF_STR_FINETA && state->str_fineta[i] != '\0'; i++) {
|
||||
state->str_fineta[i] = ' ';
|
||||
for (i = 0; i < PV_SIZEOF_STR_FINETA && state->display.str_fineta[i] != '\0'; i++) {
|
||||
state->display.str_fineta[i] = ' ';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -955,13 +960,13 @@ static const char *pv__format(pvstate_t state,
|
||||
* (i.e. the progress bar).
|
||||
*/
|
||||
static_portion_size = 0;
|
||||
for (segment = 0; state->format[segment].string; segment++) {
|
||||
if (state->format[segment].length < 0) {
|
||||
for (segment = 0; state->display.format[segment].string; segment++) {
|
||||
if (state->display.format[segment].length < 0) {
|
||||
continue;
|
||||
} else if (state->format[segment].length > 0) {
|
||||
static_portion_size += state->format[segment].length;
|
||||
} else if (state->display.format[segment].length > 0) {
|
||||
static_portion_size += state->display.format[segment].length;
|
||||
} else {
|
||||
static_portion_size += strlen(state->format[segment].string);
|
||||
static_portion_size += strlen(state->display.format[segment].string);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -970,20 +975,20 @@ static const char *pv__format(pvstate_t state,
|
||||
/*
|
||||
* Assemble the progress bar now we know how big it should be.
|
||||
*/
|
||||
if ((state->components_used & PV_DISPLAY_PROGRESS) != 0) {
|
||||
if ((state->display.components_used & PV_DISPLAY_PROGRESS) != 0) {
|
||||
char pct[16];
|
||||
int available_width, i;
|
||||
|
||||
strcpy(state->str_progress, "[");
|
||||
strcpy(state->display.str_progress, "[");
|
||||
|
||||
if (state->size > 0) {
|
||||
if (state->percentage < 0)
|
||||
state->percentage = 0;
|
||||
if (state->percentage > 100000)
|
||||
state->percentage = 100000;
|
||||
(void) pv_snprintf(pct, sizeof(pct), "%3ld%%", state->percentage);
|
||||
if (state->control.size > 0) {
|
||||
if (state->display.percentage < 0)
|
||||
state->display.percentage = 0;
|
||||
if (state->display.percentage > 100000)
|
||||
state->display.percentage = 100000;
|
||||
(void) pv_snprintf(pct, sizeof(pct), "%3ld%%", state->display.percentage);
|
||||
|
||||
available_width = state->width - static_portion_size - strlen(pct) - 3;
|
||||
available_width = state->control.width - static_portion_size - strlen(pct) - 3;
|
||||
|
||||
if (available_width < 0)
|
||||
available_width = 0;
|
||||
@@ -991,23 +996,23 @@ static const char *pv__format(pvstate_t state,
|
||||
if (available_width > (int) (PV_SIZEOF_STR_PROGRESS) - 16)
|
||||
available_width = PV_SIZEOF_STR_PROGRESS - 16;
|
||||
|
||||
for (i = 0; i < (available_width * state->percentage) / 100 - 1; i++) {
|
||||
for (i = 0; i < (available_width * state->display.percentage) / 100 - 1; i++) {
|
||||
if (i < available_width)
|
||||
(void) pv_strlcat(state->str_progress, "=", PV_SIZEOF_STR_PROGRESS);
|
||||
(void) pv_strlcat(state->display.str_progress, "=", PV_SIZEOF_STR_PROGRESS);
|
||||
}
|
||||
if (i < available_width) {
|
||||
(void) pv_strlcat(state->str_progress, ">", PV_SIZEOF_STR_PROGRESS);
|
||||
(void) pv_strlcat(state->display.str_progress, ">", PV_SIZEOF_STR_PROGRESS);
|
||||
i++;
|
||||
}
|
||||
for (; i < available_width; i++) {
|
||||
(void) pv_strlcat(state->str_progress, " ", PV_SIZEOF_STR_PROGRESS);
|
||||
(void) pv_strlcat(state->display.str_progress, " ", PV_SIZEOF_STR_PROGRESS);
|
||||
}
|
||||
(void) pv_strlcat(state->str_progress, "] ", PV_SIZEOF_STR_PROGRESS);
|
||||
(void) pv_strlcat(state->str_progress, pct, PV_SIZEOF_STR_PROGRESS);
|
||||
(void) pv_strlcat(state->display.str_progress, "] ", PV_SIZEOF_STR_PROGRESS);
|
||||
(void) pv_strlcat(state->display.str_progress, pct, PV_SIZEOF_STR_PROGRESS);
|
||||
} else {
|
||||
int p = state->percentage;
|
||||
int p = state->display.percentage;
|
||||
|
||||
available_width = state->width - static_portion_size - 5;
|
||||
available_width = state->control.width - static_portion_size - 5;
|
||||
|
||||
if (available_width < 0)
|
||||
available_width = 0;
|
||||
@@ -1021,34 +1026,34 @@ static const char *pv__format(pvstate_t state,
|
||||
p = 200 - p;
|
||||
for (i = 0; i < (available_width * p) / 100; i++) {
|
||||
if (i < available_width)
|
||||
(void) pv_strlcat(state->str_progress, " ", PV_SIZEOF_STR_PROGRESS);
|
||||
(void) pv_strlcat(state->display.str_progress, " ", PV_SIZEOF_STR_PROGRESS);
|
||||
}
|
||||
(void) pv_strlcat(state->str_progress, "<=>", PV_SIZEOF_STR_PROGRESS);
|
||||
(void) pv_strlcat(state->display.str_progress, "<=>", PV_SIZEOF_STR_PROGRESS);
|
||||
for (; i < available_width; i++) {
|
||||
(void) pv_strlcat(state->str_progress, " ", PV_SIZEOF_STR_PROGRESS);
|
||||
(void) pv_strlcat(state->display.str_progress, " ", PV_SIZEOF_STR_PROGRESS);
|
||||
}
|
||||
(void) pv_strlcat(state->str_progress, "]", PV_SIZEOF_STR_PROGRESS);
|
||||
(void) pv_strlcat(state->display.str_progress, "]", PV_SIZEOF_STR_PROGRESS);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the progress bar won't fit, drop it.
|
||||
*/
|
||||
if (strlen(state->str_progress) + static_portion_size > state->width)
|
||||
state->str_progress[0] = '\0';
|
||||
if (strlen(state->display.str_progress) + static_portion_size > state->control.width)
|
||||
state->display.str_progress[0] = '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
* We can now build the output string using the format structure.
|
||||
*/
|
||||
|
||||
state->display_buffer[0] = '\0';
|
||||
state->display.display_buffer[0] = '\0';
|
||||
display_string_length = 0;
|
||||
for (segment = 0; state->format[segment].string; segment++) {
|
||||
for (segment = 0; state->display.format[segment].string; segment++) {
|
||||
int segment_length;
|
||||
if (state->format[segment].length > 0) {
|
||||
segment_length = state->format[segment].length;
|
||||
if (state->display.format[segment].length > 0) {
|
||||
segment_length = state->display.format[segment].length;
|
||||
} else {
|
||||
segment_length = strlen(state->format[segment].string);
|
||||
segment_length = strlen(state->display.format[segment].string);
|
||||
}
|
||||
/* Skip empty segments */
|
||||
if (segment_length == 0)
|
||||
@@ -1057,14 +1062,14 @@ static const char *pv__format(pvstate_t state,
|
||||
* Truncate segment if it would make the display string
|
||||
* overflow the buffer
|
||||
*/
|
||||
if (segment_length + display_string_length > state->display_buffer_size - 2)
|
||||
segment_length = state->display_buffer_size - display_string_length - 2;
|
||||
if (segment_length + display_string_length > state->display.display_buffer_size - 2)
|
||||
segment_length = state->display.display_buffer_size - display_string_length - 2;
|
||||
if (segment_length < 1)
|
||||
break;
|
||||
/* Skip segment if it would make the display too wide */
|
||||
if (segment_length + display_string_length > (int) (state->width))
|
||||
if (segment_length + display_string_length > (int) (state->control.width))
|
||||
break;
|
||||
strncat(state->display_buffer, state->format[segment].string, segment_length);
|
||||
strncat(state->display.display_buffer, state->display.format[segment].string, segment_length);
|
||||
display_string_length += segment_length;
|
||||
}
|
||||
|
||||
@@ -1072,12 +1077,12 @@ static const char *pv__format(pvstate_t state,
|
||||
* If the size of our output shrinks, we need to keep appending
|
||||
* spaces at the end, so that we don't leave dangling bits behind.
|
||||
*/
|
||||
output_length = strlen(state->display_buffer);
|
||||
if ((output_length < state->prev_length)
|
||||
&& ((int) (state->width) >= state->prev_width)) {
|
||||
output_length = strlen(state->display.display_buffer);
|
||||
if ((output_length < state->display.prev_length)
|
||||
&& ((int) (state->control.width) >= state->display.prev_width)) {
|
||||
char spaces[32];
|
||||
int spaces_to_add;
|
||||
spaces_to_add = state->prev_length - output_length;
|
||||
spaces_to_add = state->display.prev_length - output_length;
|
||||
/* Upper boundary on number of spaces */
|
||||
if (spaces_to_add > 15) {
|
||||
spaces_to_add = 15;
|
||||
@@ -1087,12 +1092,12 @@ static const char *pv__format(pvstate_t state,
|
||||
while (--spaces_to_add >= 0) {
|
||||
spaces[spaces_to_add] = ' ';
|
||||
}
|
||||
(void) pv_strlcat(state->display_buffer, spaces, state->display_buffer_size);
|
||||
(void) pv_strlcat(state->display.display_buffer, spaces, state->display.display_buffer_size);
|
||||
}
|
||||
state->prev_width = state->width;
|
||||
state->prev_length = output_length;
|
||||
state->display.prev_width = state->control.width;
|
||||
state->display.prev_length = output_length;
|
||||
|
||||
return state->display_buffer;
|
||||
return state->display.display_buffer;
|
||||
}
|
||||
|
||||
|
||||
@@ -1118,9 +1123,9 @@ void pv_display(pvstate_t state, long double esec, off_t sl, off_t tot)
|
||||
* If the display options need reparsing, do so to generate new
|
||||
* formatting parameters.
|
||||
*/
|
||||
if (state->reparse_display) {
|
||||
if (state->flag.reparse_display) {
|
||||
pv__format_init(state);
|
||||
state->reparse_display = 0;
|
||||
state->flag.reparse_display = 0;
|
||||
}
|
||||
|
||||
pv_sig_checkbg();
|
||||
@@ -1129,18 +1134,18 @@ void pv_display(pvstate_t state, long double esec, off_t sl, off_t tot)
|
||||
if (NULL == display)
|
||||
return;
|
||||
|
||||
if (state->numeric) {
|
||||
if (state->control.numeric) {
|
||||
pv_write_retry(STDERR_FILENO, display, strlen(display));
|
||||
} else if (state->cursor) {
|
||||
if (state->force || pv_in_foreground()) {
|
||||
} else if (state->control.cursor) {
|
||||
if (state->control.force || pv_in_foreground()) {
|
||||
pv_crs_update(state, display);
|
||||
state->display_visible = true;
|
||||
state->display.display_visible = true;
|
||||
}
|
||||
} else {
|
||||
if (state->force || pv_in_foreground()) {
|
||||
if (state->control.force || pv_in_foreground()) {
|
||||
pv_write_retry(STDERR_FILENO, display, strlen(display));
|
||||
pv_write_retry(STDERR_FILENO, "\r", 1);
|
||||
state->display_visible = true;
|
||||
state->display.display_visible = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+44
-44
@@ -45,25 +45,25 @@ static off_t pv_calc_total_bytes(pvstate_t state)
|
||||
/*
|
||||
* No files specified - check stdin.
|
||||
*/
|
||||
if ((state->input_file_count < 1) || (NULL == state->input_files)) {
|
||||
if ((state->files.file_count < 1) || (NULL == state->files.filename)) {
|
||||
if (0 == fstat(STDIN_FILENO, &sb))
|
||||
total = sb.st_size;
|
||||
return total;
|
||||
}
|
||||
|
||||
for (file_idx = 0; file_idx < state->input_file_count; file_idx++) {
|
||||
for (file_idx = 0; file_idx < state->files.file_count; file_idx++) {
|
||||
int rc;
|
||||
|
||||
if (0 == strcmp(state->input_files[file_idx], "-")) {
|
||||
if (0 == strcmp(state->files.filename[file_idx], "-")) {
|
||||
rc = fstat(STDIN_FILENO, &sb);
|
||||
if (rc != 0) {
|
||||
total = 0;
|
||||
return total;
|
||||
}
|
||||
} else {
|
||||
rc = stat(state->input_files[file_idx], &sb);
|
||||
rc = stat(state->files.filename[file_idx], &sb);
|
||||
if (0 == rc) {
|
||||
rc = access(state->input_files[file_idx], R_OK); /* flawfinder: ignore */
|
||||
rc = access(state->files.filename[file_idx], R_OK); /* flawfinder: ignore */
|
||||
/*
|
||||
* flawfinder rationale: we're not really
|
||||
* using access() to do permissions checks,
|
||||
@@ -79,7 +79,7 @@ static off_t pv_calc_total_bytes(pvstate_t state)
|
||||
}
|
||||
|
||||
if (rc != 0) {
|
||||
debug("%s: %s", state->input_files[file_idx], strerror(errno));
|
||||
debug("%s: %s", state->files.filename[file_idx], strerror(errno));
|
||||
total = 0;
|
||||
return total;
|
||||
}
|
||||
@@ -91,7 +91,7 @@ static off_t pv_calc_total_bytes(pvstate_t state)
|
||||
* Get the size of block devices by opening
|
||||
* them and seeking to the end.
|
||||
*/
|
||||
if (0 == strcmp(state->input_files[file_idx], "-")) {
|
||||
if (0 == strcmp(state->files.filename[file_idx], "-")) {
|
||||
fd = open("/dev/stdin", O_RDONLY); /* flawfinder: ignore */
|
||||
/*
|
||||
* flawfinder rationale: "/dev/stdin" may be
|
||||
@@ -101,7 +101,7 @@ static off_t pv_calc_total_bytes(pvstate_t state)
|
||||
* be under the control of someone else.
|
||||
*/
|
||||
} else {
|
||||
fd = open(state->input_files[file_idx], O_RDONLY); /* flawfinder: ignore */
|
||||
fd = open(state->files.filename[file_idx], O_RDONLY); /* flawfinder: ignore */
|
||||
/* flawfinder - see last open() below. */
|
||||
}
|
||||
if (fd >= 0) {
|
||||
@@ -146,7 +146,7 @@ static off_t pv_calc_total_bytes(pvstate_t state)
|
||||
if (lseek(STDOUT_FILENO, 0, SEEK_SET) != 0) {
|
||||
pv_error(state, "%s: %s: %s", "(stdout)",
|
||||
_("failed to seek to start of output"), strerror(errno));
|
||||
state->exit_status |= 2;
|
||||
state->status.exit_status |= 2;
|
||||
}
|
||||
/*
|
||||
* If we worked out a size, then set the
|
||||
@@ -155,7 +155,7 @@ static off_t pv_calc_total_bytes(pvstate_t state)
|
||||
* device.
|
||||
*/
|
||||
if (total > 0) {
|
||||
state->stop_at_size = true;
|
||||
state->control.stop_at_size = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -182,11 +182,11 @@ static off_t pv_calc_total_lines(pvstate_t state)
|
||||
|
||||
total = 0;
|
||||
|
||||
for (file_idx = 0; file_idx < state->input_file_count && NULL != state->input_files; file_idx++) {
|
||||
for (file_idx = 0; file_idx < state->files.file_count && NULL != state->files.filename; file_idx++) {
|
||||
int fd = -1;
|
||||
int rc = 0;
|
||||
|
||||
if (0 == strcmp(state->input_files[file_idx], "-")) {
|
||||
if (0 == strcmp(state->files.filename[file_idx], "-")) {
|
||||
rc = fstat(STDIN_FILENO, &sb);
|
||||
if ((rc != 0) || (!S_ISREG(sb.st_mode))) {
|
||||
total = 0;
|
||||
@@ -194,17 +194,17 @@ static off_t pv_calc_total_lines(pvstate_t state)
|
||||
}
|
||||
fd = dup(STDIN_FILENO);
|
||||
} else {
|
||||
rc = stat(state->input_files[file_idx], &sb);
|
||||
rc = stat(state->files.filename[file_idx], &sb);
|
||||
if ((rc != 0) || (!S_ISREG(sb.st_mode))) {
|
||||
total = 0;
|
||||
return total;
|
||||
}
|
||||
fd = open(state->input_files[file_idx], O_RDONLY); /* flawfinder: ignore */
|
||||
fd = open(state->files.filename[file_idx], O_RDONLY); /* flawfinder: ignore */
|
||||
/* flawfinder - see last open() below. */
|
||||
}
|
||||
|
||||
if (fd < 0) {
|
||||
debug("%s: %s", state->input_files[file_idx], strerror(errno));
|
||||
debug("%s: %s", state->files.filename[file_idx], strerror(errno));
|
||||
total = 0;
|
||||
return total;
|
||||
}
|
||||
@@ -227,14 +227,14 @@ static off_t pv_calc_total_lines(pvstate_t state)
|
||||
* OK.
|
||||
*/
|
||||
if (numread < 0) {
|
||||
pv_error(state, "%s: %s", state->input_files[file_idx], strerror(errno));
|
||||
state->exit_status |= 2;
|
||||
pv_error(state, "%s: %s", state->files.filename[file_idx], strerror(errno));
|
||||
state->status.exit_status |= 2;
|
||||
break;
|
||||
} else if (0 == numread) {
|
||||
break;
|
||||
}
|
||||
for (buf_idx = 0; buf_idx < numread; buf_idx++) {
|
||||
if (state->null_terminated_lines) {
|
||||
if (state->control.null_terminated_lines) {
|
||||
if ('\0' == scanbuf[buf_idx])
|
||||
total++;
|
||||
} else {
|
||||
@@ -245,8 +245,8 @@ static off_t pv_calc_total_lines(pvstate_t state)
|
||||
}
|
||||
|
||||
if (0 != lseek(fd, 0, SEEK_SET)) {
|
||||
pv_error(state, "%s: %s", state->input_files[file_idx], strerror(errno));
|
||||
state->exit_status |= 2;
|
||||
pv_error(state, "%s: %s", state->files.filename[file_idx], strerror(errno));
|
||||
state->status.exit_status |= 2;
|
||||
}
|
||||
|
||||
(void) close(fd);
|
||||
@@ -259,13 +259,13 @@ static off_t pv_calc_total_lines(pvstate_t state)
|
||||
/*
|
||||
* Work out the total size of all data by adding up the sizes of all input
|
||||
* files, using either pv_calc_total_bytes() or pv_calc_total_lines()
|
||||
* depending on whether state->linemode is true.
|
||||
* depending on whether state->control.linemode is true.
|
||||
*
|
||||
* Returns the total size, or 0 if it is unknown.
|
||||
*/
|
||||
off_t pv_calc_total_size(pvstate_t state)
|
||||
{
|
||||
if (state->linemode) {
|
||||
if (state->control.linemode) {
|
||||
return pv_calc_total_lines(state);
|
||||
} else {
|
||||
return pv_calc_total_bytes(state);
|
||||
@@ -279,7 +279,7 @@ off_t pv_calc_total_size(pvstate_t state)
|
||||
* error). It is an error if the next input file is the same as the file
|
||||
* stdout is pointing to.
|
||||
*
|
||||
* Updates state->current_input_file in the process.
|
||||
* Updates state->status.current_input_file in the process.
|
||||
*/
|
||||
int pv_next_file(pvstate_t state, unsigned int filenum, int oldfd)
|
||||
{
|
||||
@@ -291,21 +291,21 @@ int pv_next_file(pvstate_t state, unsigned int filenum, int oldfd)
|
||||
if (oldfd >= 0) {
|
||||
if (0 != close(oldfd)) {
|
||||
pv_error(state, "%s: %s", _("failed to close file"), strerror(errno));
|
||||
state->exit_status |= 8;
|
||||
state->status.exit_status |= 8;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (filenum >= state->input_file_count) {
|
||||
debug("%s: %d >= %d", "filenum too large", filenum, state->input_file_count);
|
||||
state->exit_status |= 8;
|
||||
if (filenum >= state->files.file_count) {
|
||||
debug("%s: %d >= %d", "filenum too large", filenum, state->files.file_count);
|
||||
state->status.exit_status |= 8;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((NULL == state->input_files) || (0 == strcmp(state->input_files[filenum], "-"))) {
|
||||
if ((NULL == state->files.filename) || (0 == strcmp(state->files.filename[filenum], "-"))) {
|
||||
fd = STDIN_FILENO;
|
||||
} else {
|
||||
fd = open(state->input_files[filenum], O_RDONLY); /* flawfinder: ignore */
|
||||
fd = open(state->files.filename[filenum], O_RDONLY); /* flawfinder: ignore */
|
||||
/*
|
||||
* flawfinder rationale: the input file list is under the
|
||||
* control of the operator by its nature, so we can't refuse
|
||||
@@ -313,24 +313,24 @@ int pv_next_file(pvstate_t state, unsigned int filenum, int oldfd)
|
||||
*/
|
||||
if (fd < 0) {
|
||||
pv_error(state, "%s: %s: %s",
|
||||
_("failed to read file"), state->input_files[filenum], strerror(errno));
|
||||
state->exit_status |= 2;
|
||||
_("failed to read file"), state->files.filename[filenum], strerror(errno));
|
||||
state->status.exit_status |= 2;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (0 != fstat(fd, &isb)) {
|
||||
pv_error(state, "%s: %s: %s", _("failed to stat file"),
|
||||
NULL == state->input_files ? "-" : state->input_files[filenum], strerror(errno));
|
||||
NULL == state->files.filename ? "-" : state->files.filename[filenum], strerror(errno));
|
||||
(void) close(fd);
|
||||
state->exit_status |= 2;
|
||||
state->status.exit_status |= 2;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (0 != fstat(STDOUT_FILENO, &osb)) {
|
||||
pv_error(state, "%s: %s", _("failed to stat output file"), strerror(errno));
|
||||
(void) close(fd);
|
||||
state->exit_status |= 2;
|
||||
state->status.exit_status |= 2;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -351,18 +351,18 @@ int pv_next_file(pvstate_t state, unsigned int filenum, int oldfd)
|
||||
|
||||
if (input_file_is_stdout) {
|
||||
pv_error(state, "%s: %s", _("input file is output file"),
|
||||
NULL == state->input_files ? "-" : state->input_files[filenum]);
|
||||
NULL == state->files.filename ? "-" : state->files.filename[filenum]);
|
||||
(void) close(fd);
|
||||
state->exit_status |= 4;
|
||||
state->status.exit_status |= 4;
|
||||
return -1;
|
||||
}
|
||||
|
||||
state->current_input_file = filenum;
|
||||
state->status.current_input_file = filenum;
|
||||
#ifdef O_DIRECT
|
||||
/*
|
||||
* Set or clear O_DIRECT on the file descriptor.
|
||||
*/
|
||||
if (0 != fcntl(fd, F_SETFL, (state->direct_io ? O_DIRECT : 0) | fcntl(fd, F_GETFL))) {
|
||||
if (0 != fcntl(fd, F_SETFL, (state->control.direct_io ? O_DIRECT : 0) | fcntl(fd, F_GETFL))) {
|
||||
/*@-compdef@ */
|
||||
/*
|
||||
* splint - passed or returned storage is undefined - but at
|
||||
@@ -400,7 +400,7 @@ int pv_next_file(pvstate_t state, unsigned int filenum, int oldfd)
|
||||
/*@-statictrans@ */
|
||||
/*
|
||||
* Here we are doing bad things with regards to whether the returned
|
||||
* string is an allocated string from the state->input_files array,
|
||||
* string is an allocated string from the state->files.filename array,
|
||||
* a constant string, or a returned string from gettext(), but it
|
||||
* has no impact. We explicitly document, above, that the returned
|
||||
* string expires with the state, and hence switch off the
|
||||
@@ -418,15 +418,15 @@ int pv_next_file(pvstate_t state, unsigned int filenum, int oldfd)
|
||||
if (NULL == str_stdin)
|
||||
str_stdin = "(stdin)";
|
||||
|
||||
if (state->current_input_file < 0)
|
||||
if (state->status.current_input_file < 0)
|
||||
return str_none;
|
||||
if ((unsigned int) (state->current_input_file) >= state->input_file_count)
|
||||
if ((unsigned int) (state->status.current_input_file) >= state->files.file_count)
|
||||
return str_none;
|
||||
|
||||
if (NULL == state->input_files) {
|
||||
if (NULL == state->files.filename) {
|
||||
input_file_name = NULL;
|
||||
} else {
|
||||
input_file_name = state->input_files[state->current_input_file];
|
||||
input_file_name = state->files.filename[state->status.current_input_file];
|
||||
}
|
||||
if (NULL == input_file_name)
|
||||
return str_none;
|
||||
@@ -437,7 +437,7 @@ int pv_next_file(pvstate_t state, unsigned int filenum, int oldfd)
|
||||
return input_file_name;
|
||||
/*@+compdef@ */
|
||||
/*
|
||||
* splint warns about state->input_files being undefined, but we
|
||||
* splint warns about state->files.filename being undefined, but we
|
||||
* know it's been populated fully by the time this function is
|
||||
* called.
|
||||
*/
|
||||
|
||||
+112
-110
@@ -69,7 +69,7 @@ int pv_main_loop(pvstate_t state)
|
||||
total_written = 0;
|
||||
lineswritten = 0;
|
||||
transferred_since_last = 0;
|
||||
state->initial_offset = 0;
|
||||
state->display.initial_offset = 0;
|
||||
|
||||
memset(&cur_time, 0, sizeof(cur_time));
|
||||
memset(&start_time, 0, sizeof(start_time));
|
||||
@@ -84,11 +84,11 @@ int pv_main_loop(pvstate_t state)
|
||||
pv_elapsedtime_copy(&next_ratecheck, &cur_time);
|
||||
pv_elapsedtime_copy(&next_remotecheck, &cur_time);
|
||||
pv_elapsedtime_copy(&next_update, &cur_time);
|
||||
if ((state->delay_start > 0)
|
||||
&& (state->delay_start > state->interval)) {
|
||||
pv_elapsedtime_add_nsec(&next_update, (long long) (1000000000.0 * state->delay_start));
|
||||
if ((state->control.delay_start > 0)
|
||||
&& (state->control.delay_start > state->control.interval)) {
|
||||
pv_elapsedtime_add_nsec(&next_update, (long long) (1000000000.0 * state->control.delay_start));
|
||||
} else {
|
||||
pv_elapsedtime_add_nsec(&next_update, (long long) (1000000000.0 * state->interval));
|
||||
pv_elapsedtime_add_nsec(&next_update, (long long) (1000000000.0 * state->control.interval));
|
||||
}
|
||||
|
||||
target = 0;
|
||||
@@ -99,7 +99,7 @@ int pv_main_loop(pvstate_t state)
|
||||
* Open the first readable input file.
|
||||
*/
|
||||
fd = -1;
|
||||
while (fd < 0 && file_idx < state->input_file_count) {
|
||||
while (fd < 0 && file_idx < state->files.file_count) {
|
||||
fd = pv_next_file(state, file_idx, -1);
|
||||
if (fd < 0)
|
||||
file_idx++;
|
||||
@@ -109,9 +109,9 @@ int pv_main_loop(pvstate_t state)
|
||||
* Exit early if there was no readable input file.
|
||||
*/
|
||||
if (fd < 0) {
|
||||
if (state->cursor)
|
||||
if (state->control.cursor)
|
||||
pv_crs_fini(state);
|
||||
return state->exit_status;
|
||||
return state->status.exit_status;
|
||||
}
|
||||
#if HAVE_POSIX_FADVISE
|
||||
/* Advise the OS that we will only be reading sequentially. */
|
||||
@@ -122,10 +122,11 @@ int pv_main_loop(pvstate_t state)
|
||||
/*
|
||||
* Set or clear O_DIRECT on the output.
|
||||
*/
|
||||
if (0 != fcntl(STDOUT_FILENO, F_SETFL, (state->direct_io ? O_DIRECT : 0) | fcntl(STDOUT_FILENO, F_GETFL))) {
|
||||
if (0 !=
|
||||
fcntl(STDOUT_FILENO, F_SETFL, (state->control.direct_io ? O_DIRECT : 0) | fcntl(STDOUT_FILENO, F_GETFL))) {
|
||||
debug("%s: %s", "fcntl", strerror(errno));
|
||||
}
|
||||
state->direct_io_changed = false;
|
||||
state->control.direct_io_changed = false;
|
||||
#endif /* O_DIRECT */
|
||||
|
||||
#if HAVE_STRUCT_STAT_ST_BLKSIZE
|
||||
@@ -133,7 +134,7 @@ int pv_main_loop(pvstate_t state)
|
||||
* Set target buffer size if the initial file's block size can be
|
||||
* read and we weren't given a target buffer size.
|
||||
*/
|
||||
if (0 == state->target_buffer_size) {
|
||||
if (0 == state->control.target_buffer_size) {
|
||||
struct stat sb;
|
||||
memset(&sb, 0, sizeof(sb));
|
||||
if (0 == fstat(fd, &sb)) {
|
||||
@@ -142,13 +143,13 @@ int pv_main_loop(pvstate_t state)
|
||||
if (sz > BUFFER_SIZE_MAX) {
|
||||
sz = BUFFER_SIZE_MAX;
|
||||
}
|
||||
state->target_buffer_size = sz;
|
||||
state->control.target_buffer_size = sz;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (0 == state->target_buffer_size)
|
||||
state->target_buffer_size = BUFFER_SIZE;
|
||||
if (0 == state->control.target_buffer_size)
|
||||
state->control.target_buffer_size = BUFFER_SIZE;
|
||||
|
||||
while ((!(eof_in && eof_out)) || (!final_update)) {
|
||||
|
||||
@@ -162,17 +163,17 @@ int pv_main_loop(pvstate_t state)
|
||||
pv_elapsedtime_add_nsec(&next_remotecheck, REMOTE_INTERVAL);
|
||||
}
|
||||
|
||||
if (1 == state->pv_sig_abort)
|
||||
if (1 == state->flag.trigger_exit)
|
||||
break;
|
||||
|
||||
if (state->rate_limit > 0) {
|
||||
if (state->control.rate_limit > 0) {
|
||||
pv_elapsedtime_read(&cur_time);
|
||||
if (pv_elapsedtime_compare(&cur_time, &next_ratecheck) > 0) {
|
||||
target +=
|
||||
((long double) (state->rate_limit)) / (long double) (1000000000.0 /
|
||||
(long
|
||||
double) (RATE_GRANULARITY));
|
||||
long double burst_max = ((long double) (state->rate_limit * RATE_BURST_WINDOW));
|
||||
((long double) (state->control.rate_limit)) / (long double) (1000000000.0 /
|
||||
(long double)
|
||||
(RATE_GRANULARITY));
|
||||
long double burst_max = ((long double) (state->control.rate_limit * RATE_BURST_WINDOW));
|
||||
if (target > burst_max) {
|
||||
target = burst_max;
|
||||
}
|
||||
@@ -185,11 +186,11 @@ int pv_main_loop(pvstate_t state)
|
||||
* If we have to stop at "size" bytes, make sure we don't
|
||||
* try to write more than we're allowed to.
|
||||
*/
|
||||
if ((0 < state->size) && (state->stop_at_size)) {
|
||||
if ((state->size < (total_written + cansend))
|
||||
if ((0 < state->control.size) && (state->control.stop_at_size)) {
|
||||
if ((state->control.size < (total_written + cansend))
|
||||
|| ((0 == cansend)
|
||||
&& (0 == state->rate_limit))) {
|
||||
cansend = state->size - total_written;
|
||||
&& (0 == state->control.rate_limit))) {
|
||||
cansend = state->control.size - total_written;
|
||||
if (0 >= cansend) {
|
||||
eof_in = true;
|
||||
eof_out = true;
|
||||
@@ -197,7 +198,7 @@ int pv_main_loop(pvstate_t state)
|
||||
}
|
||||
}
|
||||
|
||||
if ((0 < state->size) && (state->stop_at_size)
|
||||
if ((0 < state->control.size) && (state->control.stop_at_size)
|
||||
&& (0 >= cansend) && eof_in && eof_out) {
|
||||
written = 0;
|
||||
} else {
|
||||
@@ -206,27 +207,27 @@ int pv_main_loop(pvstate_t state)
|
||||
|
||||
/* End on write error. */
|
||||
if (written < 0) {
|
||||
if (state->cursor)
|
||||
if (state->control.cursor)
|
||||
pv_crs_fini(state);
|
||||
return state->exit_status;
|
||||
return state->status.exit_status;
|
||||
}
|
||||
|
||||
if (state->linemode) {
|
||||
if (state->control.linemode) {
|
||||
transferred_since_last += lineswritten;
|
||||
total_written += lineswritten;
|
||||
if (state->rate_limit > 0)
|
||||
if (state->control.rate_limit > 0)
|
||||
target -= lineswritten;
|
||||
} else {
|
||||
transferred_since_last += written;
|
||||
total_written += written;
|
||||
if (state->rate_limit > 0)
|
||||
if (state->control.rate_limit > 0)
|
||||
target -= written;
|
||||
}
|
||||
|
||||
/*
|
||||
* EOF, and files remain - advance to the next file.
|
||||
*/
|
||||
while (eof_in && eof_out && file_idx < (state->input_file_count - 1)) {
|
||||
while (eof_in && eof_out && file_idx < (state->files.file_count - 1)) {
|
||||
file_idx++;
|
||||
fd = pv_next_file(state, file_idx, fd);
|
||||
if (fd >= 0) {
|
||||
@@ -241,14 +242,14 @@ int pv_main_loop(pvstate_t state)
|
||||
/* If full EOF, final update, and force a display updaate. */
|
||||
if (eof_in && eof_out) {
|
||||
final_update = true;
|
||||
if ((state->display_visible)
|
||||
|| (state->delay_start < 0.001)) {
|
||||
if ((state->display.display_visible)
|
||||
|| (state->control.delay_start < 0.001)) {
|
||||
pv_elapsedtime_copy(&next_update, &cur_time);
|
||||
}
|
||||
}
|
||||
|
||||
/* Just go round the loop again if there's no display. */
|
||||
if (state->no_display)
|
||||
if (state->control.no_display)
|
||||
continue;
|
||||
|
||||
/*
|
||||
@@ -257,9 +258,9 @@ int pv_main_loop(pvstate_t state)
|
||||
* we then count time as if we started when the first byte
|
||||
* was received.
|
||||
*/
|
||||
if (state->wait) {
|
||||
if (state->control.wait) {
|
||||
/* Restart the loop if nothing written yet. */
|
||||
if (state->linemode) {
|
||||
if (state->control.linemode) {
|
||||
if (lineswritten < 1)
|
||||
continue;
|
||||
} else {
|
||||
@@ -267,7 +268,7 @@ int pv_main_loop(pvstate_t state)
|
||||
continue;
|
||||
}
|
||||
|
||||
state->wait = 0;
|
||||
state->control.wait = 0;
|
||||
|
||||
/*
|
||||
* Reset the timer offset counter now that data
|
||||
@@ -281,7 +282,7 @@ int pv_main_loop(pvstate_t state)
|
||||
*/
|
||||
pv_sig_nopause();
|
||||
pv_elapsedtime_read(&start_time);
|
||||
pv_elapsedtime_zero(&(state->pv_sig_toffset));
|
||||
pv_elapsedtime_zero(&(state->signal.toffset));
|
||||
pv_sig_allowpause();
|
||||
|
||||
/*
|
||||
@@ -289,7 +290,7 @@ int pv_main_loop(pvstate_t state)
|
||||
* not immediately.
|
||||
*/
|
||||
pv_elapsedtime_copy(&next_update, &start_time);
|
||||
pv_elapsedtime_add_nsec(&next_update, (long long) (1000000000.0 * state->interval));
|
||||
pv_elapsedtime_add_nsec(&next_update, (long long) (1000000000.0 * state->control.interval));
|
||||
}
|
||||
|
||||
/* Restart the loop if it's not time to update the display. */
|
||||
@@ -297,7 +298,7 @@ int pv_main_loop(pvstate_t state)
|
||||
continue;
|
||||
}
|
||||
|
||||
pv_elapsedtime_add_nsec(&next_update, (long long) (1000000000.0 * state->interval));
|
||||
pv_elapsedtime_add_nsec(&next_update, (long long) (1000000000.0 * state->control.interval));
|
||||
|
||||
/* Set the "next update" time to now, if it's in the past. */
|
||||
if (pv_elapsedtime_compare(&next_update, &cur_time) < 0)
|
||||
@@ -308,7 +309,7 @@ int pv_main_loop(pvstate_t state)
|
||||
* started, plus the total time we spent stopped.
|
||||
*/
|
||||
memset(&init_time, 0, sizeof(init_time));
|
||||
pv_elapsedtime_add(&init_time, &start_time, &(state->pv_sig_toffset));
|
||||
pv_elapsedtime_add(&init_time, &start_time, &(state->signal.toffset));
|
||||
|
||||
/*
|
||||
* Now get the effective elapsed transfer time - current
|
||||
@@ -323,19 +324,19 @@ int pv_main_loop(pvstate_t state)
|
||||
transferred_since_last = -1;
|
||||
|
||||
/* Resize the display, if a resize signal was received. */
|
||||
if (1 == state->pv_sig_newsize) {
|
||||
if (1 == state->flag.terminal_resized) {
|
||||
unsigned int new_width, new_height;
|
||||
|
||||
state->pv_sig_newsize = 0;
|
||||
state->flag.terminal_resized = 0;
|
||||
|
||||
new_width = state->width;
|
||||
new_height = state->height;
|
||||
new_width = state->control.width;
|
||||
new_height = state->control.height;
|
||||
pv_screensize(&new_width, &new_height);
|
||||
|
||||
if (!state->width_set_manually)
|
||||
state->width = new_width;
|
||||
if (!state->height_set_manually)
|
||||
state->height = new_height;
|
||||
if (!state->control.width_set_manually)
|
||||
state->control.width = new_width;
|
||||
if (!state->control.height_set_manually)
|
||||
state->control.height = new_height;
|
||||
}
|
||||
|
||||
pv_display(state, elapsed_seconds, transferred_since_last, total_written);
|
||||
@@ -343,27 +344,27 @@ int pv_main_loop(pvstate_t state)
|
||||
transferred_since_last = 0;
|
||||
}
|
||||
|
||||
if (state->cursor) {
|
||||
if (state->control.cursor) {
|
||||
pv_crs_fini(state);
|
||||
} else {
|
||||
if ((!state->numeric) && (!state->no_display)
|
||||
&& (state->display_visible))
|
||||
if ((!state->control.numeric) && (!state->control.no_display)
|
||||
&& (state->display.display_visible))
|
||||
pv_write_retry(STDERR_FILENO, "\n", 1);
|
||||
}
|
||||
|
||||
if (1 == state->pv_sig_abort)
|
||||
state->exit_status |= 32;
|
||||
if (1 == state->flag.trigger_exit)
|
||||
state->status.exit_status |= 32;
|
||||
|
||||
if (fd >= 0)
|
||||
(void) close(fd);
|
||||
|
||||
return state->exit_status;
|
||||
return state->status.exit_status;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Watch the progress of file descriptor state->watch_fd in process
|
||||
* state->watch_pid and show details about the transfer on standard error
|
||||
* Watch the progress of file descriptor state->control.watch_fd in process
|
||||
* state->control.watch_pid and show details about the transfer on standard error
|
||||
* according to the given options.
|
||||
*
|
||||
* Returns nonzero on error.
|
||||
@@ -379,28 +380,28 @@ int pv_watchfd_loop(pvstate_t state)
|
||||
int rc;
|
||||
|
||||
memset(&info, 0, sizeof(info));
|
||||
info.watch_pid = state->watch_pid;
|
||||
info.watch_fd = state->watch_fd;
|
||||
info.watch_pid = state->control.watch_pid;
|
||||
info.watch_fd = state->control.watch_fd;
|
||||
rc = pv_watchfd_info(state, &info, false);
|
||||
if (0 != rc) {
|
||||
state->exit_status |= 2;
|
||||
return state->exit_status;
|
||||
state->status.exit_status |= 2;
|
||||
return state->status.exit_status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Use a size if one was passed, otherwise use the total size
|
||||
* calculated.
|
||||
*/
|
||||
if (0 >= state->size)
|
||||
state->size = info.size;
|
||||
if (0 >= state->control.size)
|
||||
state->control.size = info.size;
|
||||
|
||||
if (state->size < 1) {
|
||||
if (state->control.size < 1) {
|
||||
char *fmt;
|
||||
while (NULL != (fmt = strstr(state->default_format, "%e"))) {
|
||||
while (NULL != (fmt = strstr(state->control.default_format, "%e"))) {
|
||||
debug("%s", "zero size - removing ETA");
|
||||
/* strlen-1 here to include trailing NUL */
|
||||
memmove(fmt, fmt + 2, strlen(fmt) - 1);
|
||||
state->reparse_display = 1;
|
||||
state->flag.reparse_display = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -414,7 +415,7 @@ int pv_watchfd_loop(pvstate_t state)
|
||||
pv_elapsedtime_copy(&(info.start_time), &cur_time);
|
||||
pv_elapsedtime_copy(&next_remotecheck, &cur_time);
|
||||
pv_elapsedtime_copy(&next_update, &cur_time);
|
||||
pv_elapsedtime_add_nsec(&next_update, (long long) (1000000000.0 * state->interval));
|
||||
pv_elapsedtime_add_nsec(&next_update, (long long) (1000000000.0 * state->control.interval));
|
||||
|
||||
ended = false;
|
||||
total_written = 0;
|
||||
@@ -430,7 +431,7 @@ int pv_watchfd_loop(pvstate_t state)
|
||||
pv_elapsedtime_add_nsec(&next_remotecheck, REMOTE_INTERVAL);
|
||||
}
|
||||
|
||||
if (1 == state->pv_sig_abort)
|
||||
if (1 == state->flag.trigger_exit)
|
||||
break;
|
||||
|
||||
position_now = pv_watchfd_position(&info);
|
||||
@@ -441,7 +442,7 @@ int pv_watchfd_loop(pvstate_t state)
|
||||
transferred_since_last += position_now - total_written;
|
||||
total_written = position_now;
|
||||
if (first_check) {
|
||||
state->initial_offset = position_now;
|
||||
state->display.initial_offset = position_now;
|
||||
first_check = false;
|
||||
}
|
||||
}
|
||||
@@ -462,7 +463,7 @@ int pv_watchfd_loop(pvstate_t state)
|
||||
continue;
|
||||
}
|
||||
|
||||
pv_elapsedtime_add_nsec(&next_update, (long long) (1000000000.0 * state->interval));
|
||||
pv_elapsedtime_add_nsec(&next_update, (long long) (1000000000.0 * state->control.interval));
|
||||
|
||||
/* Set the "next update" time to now, if it's in the past. */
|
||||
if (pv_elapsedtime_compare(&next_update, &cur_time) < 0)
|
||||
@@ -472,7 +473,7 @@ int pv_watchfd_loop(pvstate_t state)
|
||||
* Calculate the effective start time: the time we actually
|
||||
* started, plus the total time we spent stopped.
|
||||
*/
|
||||
pv_elapsedtime_add(&init_time, &(info.start_time), &(state->pv_sig_toffset));
|
||||
pv_elapsedtime_add(&init_time, &(info.start_time), &(state->signal.toffset));
|
||||
|
||||
/*
|
||||
* Now get the effective elapsed transfer time - current
|
||||
@@ -486,19 +487,19 @@ int pv_watchfd_loop(pvstate_t state)
|
||||
transferred_since_last = -1;
|
||||
|
||||
/* Resize the display, if a resize signal was received. */
|
||||
if (1 == state->pv_sig_newsize) {
|
||||
if (1 == state->flag.terminal_resized) {
|
||||
unsigned int new_width, new_height;
|
||||
|
||||
state->pv_sig_newsize = 0;
|
||||
state->flag.terminal_resized = 0;
|
||||
|
||||
new_width = state->width;
|
||||
new_height = state->height;
|
||||
new_width = state->control.width;
|
||||
new_height = state->control.height;
|
||||
pv_screensize(&new_width, &new_height);
|
||||
|
||||
if (!state->width_set_manually)
|
||||
state->width = new_width;
|
||||
if (!state->height_set_manually)
|
||||
state->height = new_height;
|
||||
if (!state->control.width_set_manually)
|
||||
state->control.width = new_width;
|
||||
if (!state->control.height_set_manually)
|
||||
state->control.height = new_height;
|
||||
}
|
||||
|
||||
pv_display(state, elapsed_seconds, transferred_since_last, total_written);
|
||||
@@ -506,18 +507,18 @@ int pv_watchfd_loop(pvstate_t state)
|
||||
transferred_since_last = 0;
|
||||
}
|
||||
|
||||
if (!state->numeric)
|
||||
if (!state->control.numeric)
|
||||
pv_write_retry(STDERR_FILENO, "\n", 1);
|
||||
|
||||
if (1 == state->pv_sig_abort)
|
||||
state->exit_status |= 32;
|
||||
if (1 == state->flag.trigger_exit)
|
||||
state->status.exit_status |= 32;
|
||||
|
||||
return state->exit_status;
|
||||
return state->status.exit_status;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Watch the progress of all file descriptors in process state->watch_pid
|
||||
* Watch the progress of all file descriptors in process state->control.watch_pid
|
||||
* and show details about the transfers on standard error according to the
|
||||
* given options.
|
||||
*
|
||||
@@ -541,9 +542,9 @@ int pv_watchpid_loop(pvstate_t state)
|
||||
* Make sure the process exists first, so we can give an error if
|
||||
* it's not there at the start.
|
||||
*/
|
||||
if (kill(state->watch_pid, 0) != 0) {
|
||||
pv_error(state, "%s %u: %s", _("pid"), state->watch_pid, strerror(errno));
|
||||
state->exit_status |= 2;
|
||||
if (kill(state->control.watch_pid, 0) != 0) {
|
||||
pv_error(state, "%s %u: %s", _("pid"), state->control.watch_pid, strerror(errno));
|
||||
state->status.exit_status |= 2;
|
||||
return 2;
|
||||
}
|
||||
|
||||
@@ -557,7 +558,8 @@ int pv_watchpid_loop(pvstate_t state)
|
||||
* Make sure there's a format string, and then insert %N into it if
|
||||
* it's not present.
|
||||
*/
|
||||
original_format_string = state->format_string ? state->format_string : state->default_format;
|
||||
original_format_string =
|
||||
state->control.format_string ? state->control.format_string : state->control.default_format;
|
||||
memset(new_format_string, 0, sizeof(new_format_string));
|
||||
if (NULL == strstr(original_format_string, "%N")) {
|
||||
(void) pv_snprintf(new_format_string, sizeof(new_format_string), "%%N %s", original_format_string);
|
||||
@@ -565,9 +567,9 @@ int pv_watchpid_loop(pvstate_t state)
|
||||
(void) pv_snprintf(new_format_string, sizeof(new_format_string), "%s", original_format_string);
|
||||
}
|
||||
new_format_string[sizeof(new_format_string) - 1] = '\0';
|
||||
state_copy.format_string = NULL;
|
||||
(void) pv_snprintf(state_copy.default_format, PV_SIZEOF_DEFAULT_FORMAT, "%.510s", new_format_string);
|
||||
state_copy.default_format[PV_SIZEOF_DEFAULT_FORMAT - 1] = '\0';
|
||||
state_copy.control.format_string = NULL;
|
||||
(void) pv_snprintf(state_copy.control.default_format, PV_SIZEOF_DEFAULT_FORMAT, "%.510s", new_format_string);
|
||||
state_copy.control.default_format[PV_SIZEOF_DEFAULT_FORMAT - 1] = '\0';
|
||||
|
||||
/*
|
||||
* Get things ready for the main loop.
|
||||
@@ -578,7 +580,7 @@ int pv_watchpid_loop(pvstate_t state)
|
||||
|
||||
pv_elapsedtime_read(&cur_time);
|
||||
pv_elapsedtime_copy(&next_update, &cur_time);
|
||||
pv_elapsedtime_add_nsec(&next_update, (long long) (1000000000.0 * state->interval));
|
||||
pv_elapsedtime_add_nsec(&next_update, (long long) (1000000000.0 * state->control.interval));
|
||||
|
||||
for (idx = 0; idx < FD_SETSIZE; idx++) {
|
||||
fd_to_idx[idx] = -1;
|
||||
@@ -589,15 +591,15 @@ int pv_watchpid_loop(pvstate_t state)
|
||||
while (true) {
|
||||
int rc, fd, displayed_lines;
|
||||
|
||||
if (1 == state->pv_sig_abort)
|
||||
if (1 == state->flag.trigger_exit)
|
||||
break;
|
||||
|
||||
pv_elapsedtime_read(&cur_time);
|
||||
|
||||
if (kill(state->watch_pid, 0) != 0) {
|
||||
if (kill(state->control.watch_pid, 0) != 0) {
|
||||
if (first_pass) {
|
||||
pv_error(state, "%s %u: %s", _("pid"), state->watch_pid, strerror(errno));
|
||||
state->exit_status |= 2;
|
||||
pv_error(state, "%s %u: %s", _("pid"), state->control.watch_pid, strerror(errno));
|
||||
state->status.exit_status |= 2;
|
||||
if (NULL != info_array)
|
||||
free(info_array);
|
||||
if (NULL != state_array)
|
||||
@@ -616,30 +618,30 @@ int pv_watchpid_loop(pvstate_t state)
|
||||
continue;
|
||||
}
|
||||
|
||||
pv_elapsedtime_add_nsec(&next_update, (long long) (1000000000.0 * state->interval));
|
||||
pv_elapsedtime_add_nsec(&next_update, (long long) (1000000000.0 * state->control.interval));
|
||||
|
||||
/* Set the "next update" time to now, if it's in the past. */
|
||||
if (pv_elapsedtime_compare(&next_update, &cur_time) < 0)
|
||||
pv_elapsedtime_copy(&next_update, &cur_time);
|
||||
|
||||
/* Resize the display, if a resize signal was received. */
|
||||
if (1 == state->pv_sig_newsize) {
|
||||
state->pv_sig_newsize = 0;
|
||||
pv_screensize(&(state->width), &(state->height));
|
||||
if (1 == state->flag.terminal_resized) {
|
||||
state->flag.terminal_resized = 0;
|
||||
pv_screensize(&(state->control.width), &(state->control.height));
|
||||
for (idx = 0; idx < array_length; idx++) {
|
||||
state_array[idx].width = state->width;
|
||||
state_array[idx].height = state->height;
|
||||
state_array[idx].control.width = state->control.width;
|
||||
state_array[idx].control.height = state->control.height;
|
||||
pv_watchpid_setname(state, &(info_array[idx]));
|
||||
state_array[idx].reparse_display = 1;
|
||||
state_array[idx].flag.reparse_display = 1;
|
||||
}
|
||||
}
|
||||
|
||||
rc = pv_watchpid_scanfds(state, &state_copy,
|
||||
state->watch_pid, &array_length, &info_array, &state_array, fd_to_idx);
|
||||
state->control.watch_pid, &array_length, &info_array, &state_array, fd_to_idx);
|
||||
if (rc != 0) {
|
||||
if (first_pass) {
|
||||
pv_error(state, "%s %u: %s", _("pid"), state->watch_pid, strerror(errno));
|
||||
state->exit_status |= 2;
|
||||
pv_error(state, "%s %u: %s", _("pid"), state->control.watch_pid, strerror(errno));
|
||||
state->status.exit_status |= 2;
|
||||
if (NULL != info_array)
|
||||
free(info_array);
|
||||
if (NULL != state_array)
|
||||
@@ -657,7 +659,7 @@ int pv_watchpid_loop(pvstate_t state)
|
||||
struct timespec init_time, transfer_elapsed;
|
||||
long double elapsed_seconds;
|
||||
|
||||
if (displayed_lines >= (int) (state->height))
|
||||
if (displayed_lines >= (int) (state->control.height))
|
||||
break;
|
||||
|
||||
idx = fd_to_idx[fd];
|
||||
@@ -701,7 +703,7 @@ int pv_watchpid_loop(pvstate_t state)
|
||||
* Calculate the effective start time: the time we actually
|
||||
* started, plus the total time we spent stopped.
|
||||
*/
|
||||
pv_elapsedtime_add(&init_time, &(info_array[idx].start_time), &(state->pv_sig_toffset));
|
||||
pv_elapsedtime_add(&init_time, &(info_array[idx].start_time), &(state->signal.toffset));
|
||||
|
||||
/*
|
||||
* Now get the effective elapsed transfer time - current
|
||||
@@ -737,7 +739,7 @@ int pv_watchpid_loop(pvstate_t state)
|
||||
unsigned int x;
|
||||
if (displayed_lines > 0)
|
||||
pv_write_retry(STDERR_FILENO, "\n", 1);
|
||||
for (x = 0; x < state->width; x++)
|
||||
for (x = 0; x < state->control.width; x++)
|
||||
pv_write_retry(STDERR_FILENO, " ", 1);
|
||||
pv_write_retry(STDERR_FILENO, "\r", 1);
|
||||
blank_lines--;
|
||||
@@ -758,7 +760,7 @@ int pv_watchpid_loop(pvstate_t state)
|
||||
blank_lines = prev_displayed_lines;
|
||||
while (blank_lines > 0) {
|
||||
unsigned int x;
|
||||
for (x = 0; x < state->width; x++)
|
||||
for (x = 0; x < state->control.width; x++)
|
||||
pv_write_retry(STDERR_FILENO, " ", 1);
|
||||
pv_write_retry(STDERR_FILENO, "\r", 1);
|
||||
blank_lines--;
|
||||
|
||||
+52
-51
@@ -45,7 +45,7 @@ static void pv_sig_ensure_tty_tostop()
|
||||
if (0 == (terminal_attributes.c_lflag & TOSTOP)) {
|
||||
terminal_attributes.c_lflag |= TOSTOP;
|
||||
if (0 == tcsetattr(STDERR_FILENO, TCSANOW, &terminal_attributes)) {
|
||||
pv_sig_state->pv_tty_tostop_added = true;
|
||||
pv_sig_state->signal.pv_tty_tostop_added = true;
|
||||
debug("%s", "set terminal TOSTOP attribute");
|
||||
} else {
|
||||
debug("%s: %s", "failed to set terminal TOSTOP attribute", strerror(errno));
|
||||
@@ -55,8 +55,9 @@ static void pv_sig_ensure_tty_tostop()
|
||||
* In "-c" mode with IPC, make all "pv -c" instances aware
|
||||
* that we set TOSTOP, so the last one can clear it on exit.
|
||||
*/
|
||||
if (pv_sig_state->cursor && (NULL != pv_sig_state->crs_shared) && (!pv_sig_state->crs_noipc)) {
|
||||
pv_sig_state->crs_shared->tty_tostop_added = true;
|
||||
if (pv_sig_state->control.cursor && (NULL != pv_sig_state->cursor.shared)
|
||||
&& (!pv_sig_state->cursor.noipc)) {
|
||||
pv_sig_state->cursor.shared->tty_tostop_added = true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -92,8 +93,8 @@ static void pv_sig_ttou( /*@unused@ */ __attribute__((unused))
|
||||
* stderr while backgrounded.
|
||||
*/
|
||||
|
||||
if (-1 == pv_sig_state->pv_sig_old_stderr)
|
||||
pv_sig_state->pv_sig_old_stderr = dup(STDERR_FILENO);
|
||||
if (-1 == pv_sig_state->signal.old_stderr)
|
||||
pv_sig_state->signal.old_stderr = dup(STDERR_FILENO);
|
||||
|
||||
if (dup2(fd, STDERR_FILENO) < 0) {
|
||||
debug("%s: %s", "failed to replace stderr", strerror(errno));
|
||||
@@ -114,7 +115,7 @@ static void pv_sig_tstp( /*@unused@ */ __attribute__((unused))
|
||||
{
|
||||
if (NULL == pv_sig_state)
|
||||
return;
|
||||
pv_elapsedtime_read(&(pv_sig_state->pv_sig_tstp_time));
|
||||
pv_elapsedtime_read(&(pv_sig_state->signal.tstp_time));
|
||||
if (0 != raise(SIGSTOP)) {
|
||||
debug("%s: %s", "raise", strerror(errno));
|
||||
}
|
||||
@@ -135,13 +136,13 @@ static void pv_sig_cont( /*@unused@ */ __attribute__((unused))
|
||||
if (NULL == pv_sig_state)
|
||||
return;
|
||||
|
||||
pv_sig_state->pv_sig_newsize = 1;
|
||||
pv_sig_state->flag.terminal_resized = 1;
|
||||
|
||||
/*
|
||||
* We can only make the time adjustments if this SIGCONT followed a
|
||||
* SIGTSTP such that we have a stop time.
|
||||
*/
|
||||
if (0 != pv_sig_state->pv_sig_tstp_time.tv_sec) {
|
||||
if (0 != pv_sig_state->signal.tstp_time.tv_sec) {
|
||||
|
||||
memset(¤t_time, 0, sizeof(current_time));
|
||||
memset(&time_spent_stopped, 0, sizeof(time_spent_stopped));
|
||||
@@ -149,27 +150,27 @@ static void pv_sig_cont( /*@unused@ */ __attribute__((unused))
|
||||
pv_elapsedtime_read(¤t_time);
|
||||
|
||||
/* time spent stopped = current time - time SIGTSTP received */
|
||||
pv_elapsedtime_subtract(&time_spent_stopped, ¤t_time, &(pv_sig_state->pv_sig_tstp_time));
|
||||
pv_elapsedtime_subtract(&time_spent_stopped, ¤t_time, &(pv_sig_state->signal.tstp_time));
|
||||
|
||||
/* add time spent stopped the total stopped-time count */
|
||||
pv_elapsedtime_add(&(pv_sig_state->pv_sig_toffset), &(pv_sig_state->pv_sig_toffset),
|
||||
pv_elapsedtime_add(&(pv_sig_state->signal.toffset), &(pv_sig_state->signal.toffset),
|
||||
&time_spent_stopped);
|
||||
|
||||
/* reset the SIGTSTP receipt time */
|
||||
pv_elapsedtime_zero(&(pv_sig_state->pv_sig_tstp_time));
|
||||
pv_elapsedtime_zero(&(pv_sig_state->signal.tstp_time));
|
||||
}
|
||||
|
||||
/*
|
||||
* Restore the old stderr, if we had replaced it.
|
||||
*/
|
||||
if (pv_sig_state->pv_sig_old_stderr != -1) {
|
||||
if (dup2(pv_sig_state->pv_sig_old_stderr, STDERR_FILENO) < 0) {
|
||||
if (pv_sig_state->signal.old_stderr != -1) {
|
||||
if (dup2(pv_sig_state->signal.old_stderr, STDERR_FILENO) < 0) {
|
||||
debug("%s: %s", "failed to restore old stderr", strerror(errno));
|
||||
}
|
||||
if (0 != close(pv_sig_state->pv_sig_old_stderr)) {
|
||||
if (0 != close(pv_sig_state->signal.old_stderr)) {
|
||||
debug("%s: %s", "failed to close duplicate old stderr", strerror(errno));
|
||||
}
|
||||
pv_sig_state->pv_sig_old_stderr = -1;
|
||||
pv_sig_state->signal.old_stderr = -1;
|
||||
}
|
||||
|
||||
pv_sig_ensure_tty_tostop();
|
||||
@@ -189,7 +190,7 @@ static void pv_sig_winch( /*@unused@ */ __attribute__((unused))
|
||||
{
|
||||
if (NULL == pv_sig_state)
|
||||
return;
|
||||
pv_sig_state->pv_sig_newsize = 1;
|
||||
pv_sig_state->flag.terminal_resized = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -202,7 +203,7 @@ static void pv_sig_term( /*@unused@ */ __attribute__((unused))
|
||||
{
|
||||
if (NULL == pv_sig_state)
|
||||
return;
|
||||
pv_sig_state->pv_sig_abort = 1;
|
||||
pv_sig_state->flag.trigger_exit = 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -219,8 +220,8 @@ static void pv_sig_usr2( /*@unused@ */ __attribute__((unused))
|
||||
return;
|
||||
if (NULL == info)
|
||||
return;
|
||||
pv_sig_state->pv_sig_rxusr2 = 1;
|
||||
pv_sig_state->pv_sig_sender = info->si_pid;
|
||||
pv_sig_state->signal.rxusr2 = 1;
|
||||
pv_sig_state->signal.sender = info->si_pid;
|
||||
}
|
||||
|
||||
|
||||
@@ -232,11 +233,11 @@ bool pv_sigusr2_received(pvstate_t state, pid_t * pid)
|
||||
{
|
||||
if (NULL == state)
|
||||
return false;
|
||||
if (0 == state->pv_sig_rxusr2)
|
||||
if (0 == state->signal.rxusr2)
|
||||
return false;
|
||||
if (NULL != pid)
|
||||
*pid = state->pv_sig_sender;
|
||||
state->pv_sig_rxusr2 = 0;
|
||||
*pid = state->signal.sender;
|
||||
state->signal.rxusr2 = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -261,9 +262,9 @@ void pv_sig_init(pvstate_t state)
|
||||
|
||||
pv_sig_state = state;
|
||||
|
||||
pv_sig_state->pv_sig_old_stderr = -1;
|
||||
pv_elapsedtime_zero(&(pv_sig_state->pv_sig_tstp_time));
|
||||
pv_elapsedtime_zero(&(pv_sig_state->pv_sig_toffset));
|
||||
pv_sig_state->signal.old_stderr = -1;
|
||||
pv_elapsedtime_zero(&(pv_sig_state->signal.tstp_time));
|
||||
pv_elapsedtime_zero(&(pv_sig_state->signal.toffset));
|
||||
|
||||
/*
|
||||
* Note that we cast all sigemptyset() and sigaction() return values
|
||||
@@ -278,7 +279,7 @@ void pv_sig_init(pvstate_t state)
|
||||
sa.sa_handler = SIG_IGN;
|
||||
(void) sigemptyset(&(sa.sa_mask));
|
||||
sa.sa_flags = 0;
|
||||
(void) sigaction(SIGPIPE, &sa, &(pv_sig_state->pv_sig_old_sigpipe));
|
||||
(void) sigaction(SIGPIPE, &sa, &(pv_sig_state->signal.old_sigpipe));
|
||||
|
||||
/*
|
||||
* Handle SIGTTOU by continuing with output switched off, so that we
|
||||
@@ -287,7 +288,7 @@ void pv_sig_init(pvstate_t state)
|
||||
sa.sa_handler = pv_sig_ttou;
|
||||
(void) sigemptyset(&(sa.sa_mask));
|
||||
sa.sa_flags = 0;
|
||||
(void) sigaction(SIGTTOU, &sa, &(pv_sig_state->pv_sig_old_sigttou));
|
||||
(void) sigaction(SIGTTOU, &sa, &(pv_sig_state->signal.old_sigttou));
|
||||
|
||||
/*
|
||||
* Handle SIGTSTP by storing the time the signal happened for later
|
||||
@@ -296,7 +297,7 @@ void pv_sig_init(pvstate_t state)
|
||||
sa.sa_handler = pv_sig_tstp;
|
||||
(void) sigemptyset(&(sa.sa_mask));
|
||||
sa.sa_flags = 0;
|
||||
(void) sigaction(SIGTSTP, &sa, &(pv_sig_state->pv_sig_old_sigtstp));
|
||||
(void) sigaction(SIGTSTP, &sa, &(pv_sig_state->signal.old_sigtstp));
|
||||
|
||||
/*
|
||||
* Handle SIGCONT by adding the elapsed time since the last SIGTSTP
|
||||
@@ -306,7 +307,7 @@ void pv_sig_init(pvstate_t state)
|
||||
sa.sa_handler = pv_sig_cont;
|
||||
(void) sigemptyset(&(sa.sa_mask));
|
||||
sa.sa_flags = 0;
|
||||
(void) sigaction(SIGCONT, &sa, &(pv_sig_state->pv_sig_old_sigcont));
|
||||
(void) sigaction(SIGCONT, &sa, &(pv_sig_state->signal.old_sigcont));
|
||||
|
||||
/*
|
||||
* Handle SIGWINCH by setting a flag to let the main loop know it
|
||||
@@ -316,7 +317,7 @@ void pv_sig_init(pvstate_t state)
|
||||
sa.sa_handler = pv_sig_winch;
|
||||
(void) sigemptyset(&(sa.sa_mask));
|
||||
sa.sa_flags = 0;
|
||||
(void) sigaction(SIGWINCH, &sa, &(pv_sig_state->pv_sig_old_sigwinch));
|
||||
(void) sigaction(SIGWINCH, &sa, &(pv_sig_state->signal.old_sigwinch));
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -326,17 +327,17 @@ void pv_sig_init(pvstate_t state)
|
||||
sa.sa_handler = pv_sig_term;
|
||||
(void) sigemptyset(&(sa.sa_mask));
|
||||
sa.sa_flags = 0;
|
||||
(void) sigaction(SIGINT, &sa, &(pv_sig_state->pv_sig_old_sigint));
|
||||
(void) sigaction(SIGINT, &sa, &(pv_sig_state->signal.old_sigint));
|
||||
|
||||
sa.sa_handler = pv_sig_term;
|
||||
(void) sigemptyset(&(sa.sa_mask));
|
||||
sa.sa_flags = 0;
|
||||
(void) sigaction(SIGHUP, &sa, &(pv_sig_state->pv_sig_old_sighup));
|
||||
(void) sigaction(SIGHUP, &sa, &(pv_sig_state->signal.old_sighup));
|
||||
|
||||
sa.sa_handler = pv_sig_term;
|
||||
(void) sigemptyset(&(sa.sa_mask));
|
||||
sa.sa_flags = 0;
|
||||
(void) sigaction(SIGTERM, &sa, &(pv_sig_state->pv_sig_old_sigterm));
|
||||
(void) sigaction(SIGTERM, &sa, &(pv_sig_state->signal.old_sigterm));
|
||||
|
||||
#ifdef SA_SIGINFO
|
||||
/*
|
||||
@@ -349,7 +350,7 @@ void pv_sig_init(pvstate_t state)
|
||||
/*@-unrecog@ *//* splint doesn't know about SA_SIGINFO */
|
||||
sa.sa_flags = SA_SIGINFO;
|
||||
/*@+unrecog@ */
|
||||
(void) sigaction(SIGUSR2, &sa, &(pv_sig_state->pv_sig_old_sigusr2));
|
||||
(void) sigaction(SIGUSR2, &sa, &(pv_sig_state->signal.old_sigusr2));
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
#endif
|
||||
|
||||
@@ -375,23 +376,23 @@ void pv_sig_fini( /*@unused@ */ __attribute__((unused)) pvstate_t state)
|
||||
if (NULL == pv_sig_state)
|
||||
return;
|
||||
|
||||
(void) sigaction(SIGPIPE, &(pv_sig_state->pv_sig_old_sigpipe), NULL);
|
||||
(void) sigaction(SIGTTOU, &(pv_sig_state->pv_sig_old_sigttou), NULL);
|
||||
(void) sigaction(SIGTSTP, &(pv_sig_state->pv_sig_old_sigtstp), NULL);
|
||||
(void) sigaction(SIGCONT, &(pv_sig_state->pv_sig_old_sigcont), NULL);
|
||||
(void) sigaction(SIGPIPE, &(pv_sig_state->signal.old_sigpipe), NULL);
|
||||
(void) sigaction(SIGTTOU, &(pv_sig_state->signal.old_sigttou), NULL);
|
||||
(void) sigaction(SIGTSTP, &(pv_sig_state->signal.old_sigtstp), NULL);
|
||||
(void) sigaction(SIGCONT, &(pv_sig_state->signal.old_sigcont), NULL);
|
||||
#ifdef SIGWINCH
|
||||
(void) sigaction(SIGWINCH, &(pv_sig_state->pv_sig_old_sigwinch), NULL);
|
||||
(void) sigaction(SIGWINCH, &(pv_sig_state->signal.old_sigwinch), NULL);
|
||||
#endif
|
||||
(void) sigaction(SIGINT, &(pv_sig_state->pv_sig_old_sigint), NULL);
|
||||
(void) sigaction(SIGHUP, &(pv_sig_state->pv_sig_old_sighup), NULL);
|
||||
(void) sigaction(SIGTERM, &(pv_sig_state->pv_sig_old_sigterm), NULL);
|
||||
(void) sigaction(SIGINT, &(pv_sig_state->signal.old_sigint), NULL);
|
||||
(void) sigaction(SIGHUP, &(pv_sig_state->signal.old_sighup), NULL);
|
||||
(void) sigaction(SIGTERM, &(pv_sig_state->signal.old_sigterm), NULL);
|
||||
#ifdef SA_SIGINFO
|
||||
(void) sigaction(SIGUSR2, &(pv_sig_state->pv_sig_old_sigusr2), NULL);
|
||||
(void) sigaction(SIGUSR2, &(pv_sig_state->signal.old_sigusr2), NULL);
|
||||
#endif
|
||||
|
||||
need_to_clear_tostop = pv_sig_state->pv_tty_tostop_added;
|
||||
need_to_clear_tostop = pv_sig_state->signal.pv_tty_tostop_added;
|
||||
|
||||
if (pv_sig_state->cursor) {
|
||||
if (pv_sig_state->control.cursor) {
|
||||
#ifdef HAVE_IPC
|
||||
/*
|
||||
* We won't clear TOSTOP if other "pv -c" instances
|
||||
@@ -400,7 +401,7 @@ void pv_sig_fini( /*@unused@ */ __attribute__((unused)) pvstate_t state)
|
||||
* TODO: we need a better way to determine if we're the last
|
||||
* "pv" left.
|
||||
*/
|
||||
if (pv_sig_state->cursor && pv_sig_state->crs_pvcount > 1) {
|
||||
if (pv_sig_state->control.cursor && pv_sig_state->cursor.pvcount > 1) {
|
||||
need_to_clear_tostop = false;
|
||||
}
|
||||
#else /* !HAVE_IPC */
|
||||
@@ -430,7 +431,7 @@ void pv_sig_fini( /*@unused@ */ __attribute__((unused)) pvstate_t state)
|
||||
}
|
||||
}
|
||||
|
||||
pv_sig_state->pv_tty_tostop_added = false;
|
||||
pv_sig_state->signal.pv_tty_tostop_added = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -495,18 +496,18 @@ void pv_sig_checkbg(void)
|
||||
|
||||
next_check = time(NULL) + 1;
|
||||
|
||||
if (-1 == pv_sig_state->pv_sig_old_stderr)
|
||||
if (-1 == pv_sig_state->signal.old_stderr)
|
||||
return;
|
||||
|
||||
if (dup2(pv_sig_state->pv_sig_old_stderr, STDERR_FILENO) < 0) {
|
||||
if (dup2(pv_sig_state->signal.old_stderr, STDERR_FILENO) < 0) {
|
||||
debug("%s: %s", "failed to restore old stderr", strerror(errno));
|
||||
}
|
||||
|
||||
if (0 != close(pv_sig_state->pv_sig_old_stderr)) {
|
||||
if (0 != close(pv_sig_state->signal.old_stderr)) {
|
||||
debug("%s: %s", "failed to close duplicate old stderr", strerror(errno));
|
||||
}
|
||||
|
||||
pv_sig_state->pv_sig_old_stderr = -1;
|
||||
pv_sig_state->signal.old_stderr = -1;
|
||||
|
||||
pv_sig_ensure_tty_tostop();
|
||||
#ifdef HAVE_IPC
|
||||
|
||||
+111
-110
@@ -20,26 +20,26 @@
|
||||
/* alloc / realloc history buffer */
|
||||
static void pv_alloc_history(pvstate_t state)
|
||||
{
|
||||
if (NULL != state->history)
|
||||
free(state->history);
|
||||
state->history = NULL;
|
||||
if (NULL != state->display.history)
|
||||
free(state->display.history);
|
||||
state->display.history = NULL;
|
||||
|
||||
state->history = calloc((size_t) (state->history_len), sizeof(state->history[0]));
|
||||
if (NULL == state->history) {
|
||||
state->display.history = calloc((size_t) (state->display.history_len), sizeof(state->display.history[0]));
|
||||
if (NULL == state->display.history) {
|
||||
/*@-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\n", state->program_name,
|
||||
fprintf(stderr, "%s: %s: %s\n", state->status.program_name,
|
||||
_("history structure allocation failed"), strerror(errno));
|
||||
/*@+mustfreefresh@ */
|
||||
return;
|
||||
}
|
||||
|
||||
state->history_first = state->history_last = 0;
|
||||
state->history[0].elapsed_sec = 0.0; /* to be safe, memset() not recommended for doubles */
|
||||
state->display.history_first = state->display.history_last = 0;
|
||||
state->display.history[0].elapsed_sec = 0.0; /* to be safe, memset() not recommended for doubles */
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -55,44 +55,44 @@ pvstate_t pv_state_alloc(const char *program_name)
|
||||
memset(state, 0, sizeof(*state));
|
||||
|
||||
/* splint 3.1.2 thinks this is required for some reason. */
|
||||
if (NULL != state->program_name) {
|
||||
free(state->program_name);
|
||||
if (NULL != state->status.program_name) {
|
||||
free(state->status.program_name);
|
||||
}
|
||||
|
||||
state->program_name = pv_strdup(program_name);
|
||||
if (NULL == state->program_name) {
|
||||
state->status.program_name = pv_strdup(program_name);
|
||||
if (NULL == state->status.program_name) {
|
||||
free(state);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
state->watch_pid = 0;
|
||||
state->watch_fd = -1;
|
||||
state->control.watch_pid = 0;
|
||||
state->control.watch_fd = -1;
|
||||
#ifdef HAVE_IPC
|
||||
state->crs_shmid = -1;
|
||||
state->crs_pvcount = 1;
|
||||
state->cursor.shmid = -1;
|
||||
state->cursor.pvcount = 1;
|
||||
#endif /* HAVE_IPC */
|
||||
state->crs_lock_fd = -1;
|
||||
state->cursor.lock_fd = -1;
|
||||
|
||||
state->reparse_display = 1;
|
||||
state->current_input_file = -1;
|
||||
state->flag.reparse_display = 1;
|
||||
state->status.current_input_file = -1;
|
||||
#ifdef HAVE_SPLICE
|
||||
state->splice_failed_fd = -1;
|
||||
state->transfer.splice_failed_fd = -1;
|
||||
#endif /* HAVE_SPLICE */
|
||||
state->display_visible = false;
|
||||
state->display.display_visible = false;
|
||||
|
||||
/*
|
||||
* Get the current working directory, if possible, as a base for
|
||||
* showing relative filenames with --watchfd.
|
||||
*/
|
||||
if (NULL == getcwd(state->cwd, PV_SIZEOF_CWD - 1)) {
|
||||
if (NULL == getcwd(state->status.cwd, PV_SIZEOF_CWD - 1)) {
|
||||
/* failed - will always show full path */
|
||||
state->cwd[0] = '\0';
|
||||
state->status.cwd[0] = '\0';
|
||||
}
|
||||
if ('\0' == state->cwd[1]) {
|
||||
if ('\0' == state->status.cwd[1]) {
|
||||
/* CWD is root directory - always show full path */
|
||||
state->cwd[0] = '\0';
|
||||
state->status.cwd[0] = '\0';
|
||||
}
|
||||
state->cwd[PV_SIZEOF_CWD - 1] = '\0';
|
||||
state->status.cwd[PV_SIZEOF_CWD - 1] = '\0';
|
||||
|
||||
return state;
|
||||
}
|
||||
@@ -106,45 +106,45 @@ void pv_state_free(pvstate_t state)
|
||||
if (0 == state)
|
||||
return;
|
||||
|
||||
if (NULL != state->program_name)
|
||||
free(state->program_name);
|
||||
state->program_name = NULL;
|
||||
if (NULL != state->status.program_name)
|
||||
free(state->status.program_name);
|
||||
state->status.program_name = NULL;
|
||||
|
||||
if (NULL != state->display_buffer)
|
||||
free(state->display_buffer);
|
||||
state->display_buffer = NULL;
|
||||
if (NULL != state->display.display_buffer)
|
||||
free(state->display.display_buffer);
|
||||
state->display.display_buffer = NULL;
|
||||
|
||||
if (NULL != state->name) {
|
||||
free(state->name);
|
||||
state->name = NULL;
|
||||
if (NULL != state->control.name) {
|
||||
free(state->control.name);
|
||||
state->control.name = NULL;
|
||||
}
|
||||
|
||||
if (NULL != state->format_string) {
|
||||
free(state->format_string);
|
||||
state->format_string = NULL;
|
||||
if (NULL != state->control.format_string) {
|
||||
free(state->control.format_string);
|
||||
state->control.format_string = NULL;
|
||||
}
|
||||
|
||||
/*@-keeptrans@ */
|
||||
if (NULL != state->transfer_buffer)
|
||||
free(state->transfer_buffer);
|
||||
state->transfer_buffer = NULL;
|
||||
if (NULL != state->transfer.transfer_buffer)
|
||||
free(state->transfer.transfer_buffer);
|
||||
state->transfer.transfer_buffer = NULL;
|
||||
/*@+keeptrans@ */
|
||||
/* splint - explicitly freeing this structure, so free() here is OK. */
|
||||
|
||||
if (NULL != state->history)
|
||||
free(state->history);
|
||||
state->history = NULL;
|
||||
if (NULL != state->display.history)
|
||||
free(state->display.history);
|
||||
state->display.history = NULL;
|
||||
|
||||
if (NULL != state->input_files) {
|
||||
if (NULL != state->files.filename) {
|
||||
unsigned int file_idx;
|
||||
for (file_idx = 0; file_idx < state->input_file_count; file_idx++) {
|
||||
for (file_idx = 0; file_idx < state->files.file_count; file_idx++) {
|
||||
/*@-unqualifiedtrans@ */
|
||||
free(state->input_files[file_idx]);
|
||||
free(state->files.filename[file_idx]);
|
||||
/*@+unqualifiedtrans@ */
|
||||
/* splint: see similar code below. */
|
||||
}
|
||||
free(state->input_files);
|
||||
state->input_files = NULL;
|
||||
free(state->files.filename);
|
||||
state->files.filename = NULL;
|
||||
}
|
||||
|
||||
free(state);
|
||||
@@ -160,12 +160,12 @@ void pv_state_set_format(pvstate_t state, bool progress, bool timer, bool eta, b
|
||||
const char *name)
|
||||
{
|
||||
#define PV_ADDFORMAT(x,y) if (x) { \
|
||||
if (state->default_format[0] != '\0') \
|
||||
(void) pv_strlcat(state->default_format, " ", sizeof(state->default_format)); \
|
||||
(void) pv_strlcat(state->default_format, y, sizeof(state->default_format)); \
|
||||
if (state->control.default_format[0] != '\0') \
|
||||
(void) pv_strlcat(state->control.default_format, " ", sizeof(state->control.default_format)); \
|
||||
(void) pv_strlcat(state->control.default_format, y, sizeof(state->control.default_format)); \
|
||||
}
|
||||
|
||||
state->default_format[0] = '\0';
|
||||
state->control.default_format[0] = '\0';
|
||||
PV_ADDFORMAT(name, "%N");
|
||||
PV_ADDFORMAT(bytes, "%b");
|
||||
PV_ADDFORMAT(bufpercent, "%T");
|
||||
@@ -187,159 +187,159 @@ void pv_state_set_format(pvstate_t state, bool progress, bool timer, bool eta, b
|
||||
*/
|
||||
}
|
||||
|
||||
if (NULL != state->name) {
|
||||
free(state->name);
|
||||
state->name = NULL;
|
||||
if (NULL != state->control.name) {
|
||||
free(state->control.name);
|
||||
state->control.name = NULL;
|
||||
}
|
||||
|
||||
if (NULL != name)
|
||||
state->name = pv_strdup(name);
|
||||
state->control.name = pv_strdup(name);
|
||||
|
||||
state->reparse_display = 1;
|
||||
state->flag.reparse_display = 1;
|
||||
}
|
||||
|
||||
|
||||
void pv_state_force_set(pvstate_t state, bool val)
|
||||
{
|
||||
state->force = val;
|
||||
state->control.force = val;
|
||||
}
|
||||
|
||||
void pv_state_cursor_set(pvstate_t state, bool val)
|
||||
{
|
||||
state->cursor = val;
|
||||
state->control.cursor = val;
|
||||
}
|
||||
|
||||
void pv_state_numeric_set(pvstate_t state, bool val)
|
||||
{
|
||||
state->numeric = val;
|
||||
state->control.numeric = val;
|
||||
}
|
||||
|
||||
void pv_state_wait_set(pvstate_t state, bool val)
|
||||
{
|
||||
state->wait = val;
|
||||
state->control.wait = val;
|
||||
}
|
||||
|
||||
void pv_state_delay_start_set(pvstate_t state, double val)
|
||||
{
|
||||
state->delay_start = val;
|
||||
state->control.delay_start = val;
|
||||
}
|
||||
|
||||
void pv_state_linemode_set(pvstate_t state, bool val)
|
||||
{
|
||||
state->linemode = val;
|
||||
state->control.linemode = val;
|
||||
}
|
||||
|
||||
void pv_state_bits_set(pvstate_t state, bool bits)
|
||||
{
|
||||
state->bits = bits;
|
||||
state->control.bits = bits;
|
||||
}
|
||||
|
||||
void pv_state_null_terminated_lines_set(pvstate_t state, bool val)
|
||||
{
|
||||
state->null_terminated_lines = val;
|
||||
state->control.null_terminated_lines = val;
|
||||
}
|
||||
|
||||
void pv_state_no_display_set(pvstate_t state, bool val)
|
||||
{
|
||||
state->no_display = val;
|
||||
state->control.no_display = val;
|
||||
}
|
||||
|
||||
void pv_state_skip_errors_set(pvstate_t state, unsigned int val)
|
||||
{
|
||||
state->skip_errors = val;
|
||||
state->control.skip_errors = val;
|
||||
}
|
||||
|
||||
void pv_state_error_skip_block_set(pvstate_t state, off_t val)
|
||||
{
|
||||
state->error_skip_block = val;
|
||||
state->control.error_skip_block = val;
|
||||
}
|
||||
|
||||
void pv_state_stop_at_size_set(pvstate_t state, bool val)
|
||||
{
|
||||
state->stop_at_size = val;
|
||||
state->control.stop_at_size = val;
|
||||
}
|
||||
|
||||
void pv_state_sync_after_write_set(pvstate_t state, bool val)
|
||||
{
|
||||
state->sync_after_write = val;
|
||||
state->control.sync_after_write = val;
|
||||
}
|
||||
|
||||
void pv_state_direct_io_set(pvstate_t state, bool val)
|
||||
{
|
||||
state->direct_io = val;
|
||||
state->direct_io_changed = true;
|
||||
state->control.direct_io = val;
|
||||
state->control.direct_io_changed = true;
|
||||
}
|
||||
|
||||
void pv_state_discard_input_set(pvstate_t state, bool val)
|
||||
{
|
||||
state->discard_input = val;
|
||||
state->control.discard_input = val;
|
||||
}
|
||||
|
||||
void pv_state_rate_limit_set(pvstate_t state, off_t val)
|
||||
{
|
||||
state->rate_limit = val;
|
||||
state->control.rate_limit = val;
|
||||
}
|
||||
|
||||
void pv_state_target_buffer_size_set(pvstate_t state, size_t val)
|
||||
{
|
||||
state->target_buffer_size = val;
|
||||
state->control.target_buffer_size = val;
|
||||
}
|
||||
|
||||
void pv_state_no_splice_set(pvstate_t state, bool val)
|
||||
{
|
||||
state->no_splice = val;
|
||||
state->control.no_splice = val;
|
||||
}
|
||||
|
||||
void pv_state_size_set(pvstate_t state, off_t val)
|
||||
{
|
||||
state->size = val;
|
||||
state->control.size = val;
|
||||
}
|
||||
|
||||
void pv_state_interval_set(pvstate_t state, double val)
|
||||
{
|
||||
state->interval = val;
|
||||
state->control.interval = val;
|
||||
}
|
||||
|
||||
void pv_state_width_set(pvstate_t state, unsigned int val, bool was_set_manually)
|
||||
{
|
||||
state->width = val;
|
||||
state->width_set_manually = was_set_manually;
|
||||
state->control.width = val;
|
||||
state->control.width_set_manually = was_set_manually;
|
||||
}
|
||||
|
||||
void pv_state_height_set(pvstate_t state, unsigned int val, bool was_set_manually)
|
||||
{
|
||||
state->height = val;
|
||||
state->height_set_manually = was_set_manually;
|
||||
state->control.height = val;
|
||||
state->control.height_set_manually = was_set_manually;
|
||||
}
|
||||
|
||||
void pv_state_name_set(pvstate_t state, /*@null@ */ const char *val)
|
||||
{
|
||||
if (NULL != state->name) {
|
||||
free(state->name);
|
||||
state->name = NULL;
|
||||
if (NULL != state->control.name) {
|
||||
free(state->control.name);
|
||||
state->control.name = NULL;
|
||||
}
|
||||
if (NULL != val)
|
||||
state->name = pv_strdup(val);
|
||||
state->control.name = pv_strdup(val);
|
||||
}
|
||||
|
||||
void pv_state_format_string_set(pvstate_t state, /*@null@ */ const char *val)
|
||||
{
|
||||
if (NULL != state->format_string) {
|
||||
free(state->format_string);
|
||||
state->format_string = NULL;
|
||||
if (NULL != state->control.format_string) {
|
||||
free(state->control.format_string);
|
||||
state->control.format_string = NULL;
|
||||
}
|
||||
if (NULL != val)
|
||||
state->format_string = pv_strdup(val);
|
||||
state->control.format_string = pv_strdup(val);
|
||||
}
|
||||
|
||||
void pv_state_watch_pid_set(pvstate_t state, pid_t val)
|
||||
{
|
||||
state->watch_pid = val;
|
||||
state->control.watch_pid = val;
|
||||
}
|
||||
|
||||
void pv_state_watch_fd_set(pvstate_t state, int val)
|
||||
{
|
||||
state->watch_fd = val;
|
||||
state->control.watch_fd = val;
|
||||
}
|
||||
|
||||
void pv_state_average_rate_window_set(pvstate_t state, unsigned int val)
|
||||
@@ -347,11 +347,11 @@ void pv_state_average_rate_window_set(pvstate_t state, unsigned int val)
|
||||
if (val < 1)
|
||||
val = 1;
|
||||
if (val >= 20) {
|
||||
state->history_len = val / 5 + 1;
|
||||
state->history_interval = 5;
|
||||
state->display.history_len = val / 5 + 1;
|
||||
state->display.history_interval = 5;
|
||||
} else {
|
||||
state->history_len = val + 1;
|
||||
state->history_interval = 1;
|
||||
state->display.history_len = val + 1;
|
||||
state->display.history_interval = 1;
|
||||
}
|
||||
pv_alloc_history(state);
|
||||
}
|
||||
@@ -364,10 +364,10 @@ void pv_state_inputfiles(pvstate_t state, unsigned int input_file_count, const c
|
||||
{
|
||||
unsigned int file_idx;
|
||||
|
||||
if (NULL != state->input_files) {
|
||||
for (file_idx = 0; file_idx < state->input_file_count; file_idx++) {
|
||||
if (NULL != state->files.filename) {
|
||||
for (file_idx = 0; file_idx < state->files.file_count; file_idx++) {
|
||||
/*@-unqualifiedtrans@ */
|
||||
free(state->input_files[file_idx]);
|
||||
free(state->files.filename[file_idx]);
|
||||
/*@+unqualifiedtrans@ */
|
||||
/*
|
||||
* TODO: find a way to tell splint the array
|
||||
@@ -375,29 +375,30 @@ void pv_state_inputfiles(pvstate_t state, unsigned int input_file_count, const c
|
||||
* array itself.
|
||||
*/
|
||||
}
|
||||
free(state->input_files);
|
||||
state->input_files = NULL;
|
||||
state->input_file_count = 0;
|
||||
free(state->files.filename);
|
||||
state->files.filename = NULL;
|
||||
state->files.file_count = 0;
|
||||
}
|
||||
state->input_files = calloc((size_t) (input_file_count + 1), sizeof(char *));
|
||||
if (NULL == state->input_files) {
|
||||
state->files.filename = calloc((size_t) (input_file_count + 1), sizeof(char *));
|
||||
if (NULL == state->files.filename) {
|
||||
/*@-mustfreefresh@ *//* see similar _() issue above */
|
||||
fprintf(stderr, "%s: %s: %s\n", state->program_name, _("file list allocation failed"), strerror(errno));
|
||||
fprintf(stderr, "%s: %s: %s\n", state->status.program_name, _("file list allocation failed"),
|
||||
strerror(errno));
|
||||
/*@+mustfreefresh@ */
|
||||
return;
|
||||
}
|
||||
for (file_idx = 0; file_idx < input_file_count; file_idx++) {
|
||||
/*@-nullstate@ */
|
||||
state->input_files[file_idx] = pv_strdup(input_files[file_idx]);
|
||||
if (NULL == state->input_files[file_idx]) {
|
||||
state->files.filename[file_idx] = pv_strdup(input_files[file_idx]);
|
||||
if (NULL == state->files.filename[file_idx]) {
|
||||
/*@-mustfreefresh@ *//* see similar _() issue above */
|
||||
fprintf(stderr, "%s: %s: %s\n", state->program_name,
|
||||
fprintf(stderr, "%s: %s: %s\n", state->status.program_name,
|
||||
_("file list allocation failed"), strerror(errno));
|
||||
/*@+mustfreefresh@ */
|
||||
return;
|
||||
}
|
||||
}
|
||||
state->input_file_count = input_file_count;
|
||||
state->files.file_count = input_file_count;
|
||||
}
|
||||
|
||||
/*@+nullstate@*/
|
||||
|
||||
+138
-129
@@ -293,21 +293,21 @@ static ssize_t pv__transfer_write_repeated(int fd, void *buf, size_t count, bool
|
||||
* returns 1.
|
||||
*
|
||||
* At most, the number of bytes read will be the number of bytes remaining
|
||||
* in the input buffer. If state->rate_limit is >0, and/or "allowed" is >0,
|
||||
* in the input buffer. If state->control.rate_limit is >0, and/or "allowed" is >0,
|
||||
* then the maximum number of bytes read will be the number remaining unused
|
||||
* in the input buffer or the value of "allowed", whichever is smaller.
|
||||
*
|
||||
* If splice() was successfully used, sets state->splice_used to true; if it
|
||||
* failed, then state->splice_failed_fd is updated to the current fd so
|
||||
* If splice() was successfully used, sets state->transfer.splice_used to true; if it
|
||||
* failed, then state->transfer.splice_failed_fd is updated to the current fd so
|
||||
* splice() won't be tried again until the next input file.
|
||||
*
|
||||
* Updates state->read_position by the number of bytes read, unless splice()
|
||||
* Updates state->transfer.read_position by the number of bytes read, unless splice()
|
||||
* was used, in which case it does not since there's nothing in the buffer
|
||||
* (and it also adds the bytes to state->written since they've been written
|
||||
* (and it also adds the bytes to state->transfer.written since they've been written
|
||||
* to the output).
|
||||
*
|
||||
* On read error, updates state->exit_status, and if allowed by
|
||||
* state->skip_errors, tries to skip past the problem.
|
||||
* On read error, updates state->status.exit_status, and if allowed by
|
||||
* state->control.skip_errors, tries to skip past the problem.
|
||||
*
|
||||
* If the end of the input file is reached or the error is unrecoverable,
|
||||
* sets *eof_in to true. If all data in the buffer has been written at this
|
||||
@@ -324,18 +324,18 @@ static int pv__transfer_read(pvstate_t state, int fd, bool *eof_in, bool *eof_ou
|
||||
#endif /* HAVE_SPLICE */
|
||||
|
||||
do_not_skip_errors = false;
|
||||
if (0 == state->skip_errors)
|
||||
if (0 == state->control.skip_errors)
|
||||
do_not_skip_errors = true;
|
||||
|
||||
bytes_can_read = state->buffer_size - state->read_position;
|
||||
bytes_can_read = state->transfer.buffer_size - state->transfer.read_position;
|
||||
nread = 0;
|
||||
|
||||
#ifdef HAVE_SPLICE
|
||||
state->splice_used = false;
|
||||
if ((!state->linemode) && (!state->no_splice)
|
||||
&& (fd != state->splice_failed_fd)
|
||||
&& (0 == state->to_write)) {
|
||||
if (state->rate_limit > 0 || allowed != 0) {
|
||||
state->transfer.splice_used = false;
|
||||
if ((!state->control.linemode) && (!state->control.no_splice)
|
||||
&& (fd != state->transfer.splice_failed_fd)
|
||||
&& (0 == state->transfer.to_write)) {
|
||||
if (state->control.rate_limit > 0 || allowed != 0) {
|
||||
bytes_to_splice = (size_t) allowed;
|
||||
} else {
|
||||
bytes_to_splice = bytes_can_read;
|
||||
@@ -348,18 +348,18 @@ static int pv__transfer_read(pvstate_t state, int fd, bool *eof_in, bool *eof_ou
|
||||
/*@+type@ */
|
||||
/*@+nullpass@ */
|
||||
|
||||
state->splice_used = true;
|
||||
state->transfer.splice_used = true;
|
||||
if ((nread < 0) && (EINVAL == errno)) {
|
||||
debug("%s %d: %s", "fd", fd, "splice failed with EINVAL - disabling");
|
||||
state->splice_failed_fd = fd;
|
||||
state->splice_used = false;
|
||||
state->transfer.splice_failed_fd = fd;
|
||||
state->transfer.splice_used = false;
|
||||
/*
|
||||
* Fall through to read() below.
|
||||
*/
|
||||
} else if (nread > 0) {
|
||||
state->written = nread;
|
||||
state->transfer.written = nread;
|
||||
#ifdef HAVE_FDATASYNC
|
||||
if (state->sync_after_write) {
|
||||
if (state->control.sync_after_write) {
|
||||
/*
|
||||
* Ignore non IO errors, such as EBADFD (bad file
|
||||
* descriptor), EINVAL (non syncable fd, such as a
|
||||
@@ -380,14 +380,18 @@ static int pv__transfer_read(pvstate_t state, int fd, bool *eof_in, bool *eof_ou
|
||||
/* nothing read yet - do nothing */
|
||||
} else {
|
||||
/* EOF might not really be EOF, it seems */
|
||||
state->splice_used = false;
|
||||
state->transfer.splice_used = false;
|
||||
}
|
||||
}
|
||||
if (!state->splice_used) {
|
||||
nread = pv__transfer_read_repeated(fd, state->transfer_buffer + state->read_position, bytes_can_read);
|
||||
if (!state->transfer.splice_used) {
|
||||
nread =
|
||||
pv__transfer_read_repeated(fd, state->transfer.transfer_buffer + state->transfer.read_position,
|
||||
bytes_can_read);
|
||||
}
|
||||
#else
|
||||
nread = pv__transfer_read_repeated(fd, state->transfer_buffer + state->read_position, bytes_can_read);
|
||||
nread =
|
||||
pv__transfer_read_repeated(fd, state->transfer.transfer_buffer + state->transfer.read_position,
|
||||
bytes_can_read);
|
||||
#endif /* HAVE_SPLICE */
|
||||
|
||||
|
||||
@@ -399,7 +403,7 @@ static int pv__transfer_read(pvstate_t state, int fd, bool *eof_in, bool *eof_ou
|
||||
* move on to the next input file.
|
||||
*/
|
||||
*eof_in = true;
|
||||
if (state->write_position >= state->read_position)
|
||||
if (state->transfer.write_position >= state->transfer.read_position)
|
||||
*eof_out = true;
|
||||
return 1;
|
||||
} else if (nread > 0) {
|
||||
@@ -408,16 +412,16 @@ static int pv__transfer_read(pvstate_t state, int fd, bool *eof_in, bool *eof_ou
|
||||
* the error counter and update our record of how much data
|
||||
* we've got in the buffer.
|
||||
*/
|
||||
state->read_errors_in_a_row = 0;
|
||||
state->transfer.read_errors_in_a_row = 0;
|
||||
#ifdef HAVE_SPLICE
|
||||
/*
|
||||
* If we used splice(), there isn't any more data in the
|
||||
* buffer than there was before.
|
||||
*/
|
||||
if (!state->splice_used)
|
||||
state->read_position += nread;
|
||||
if (!state->transfer.splice_used)
|
||||
state->transfer.read_position += nread;
|
||||
#else
|
||||
state->read_position += nread;
|
||||
state->transfer.read_position += nread;
|
||||
#endif /* HAVE_SPLICE */
|
||||
return 1;
|
||||
}
|
||||
@@ -441,8 +445,8 @@ static int pv__transfer_read(pvstate_t state, int fd, bool *eof_in, bool *eof_ou
|
||||
* exit status, regardless of whether we're skipping errors, and
|
||||
* increment the error counter.
|
||||
*/
|
||||
state->exit_status |= 16;
|
||||
state->read_errors_in_a_row++;
|
||||
state->status.exit_status |= 16;
|
||||
state->transfer.read_errors_in_a_row++;
|
||||
|
||||
/*
|
||||
* If we aren't skipping errors, show the error and pretend we
|
||||
@@ -459,7 +463,7 @@ static int pv__transfer_read(pvstate_t state, int fd, bool *eof_in, bool *eof_ou
|
||||
* TODO: investigate and fix the reason for this.
|
||||
*/
|
||||
*eof_in = true;
|
||||
if (state->write_position >= state->read_position) {
|
||||
if (state->transfer.write_position >= state->transfer.read_position) {
|
||||
*eof_out = true;
|
||||
}
|
||||
return 1;
|
||||
@@ -471,13 +475,13 @@ static int pv__transfer_read(pvstate_t state, int fd, bool *eof_in, bool *eof_ou
|
||||
|
||||
amount_skipped = -1;
|
||||
|
||||
if (!state->read_error_warning_shown) {
|
||||
if (!state->transfer.read_error_warning_shown) {
|
||||
/*@-compdef@ */
|
||||
pv_error(state, "%s: %s: %s", pv_current_file_name(state), _("warning: read errors detected"),
|
||||
strerror(errno));
|
||||
/*@+compdef@ */
|
||||
/* splint - see previous pv_current_file_name() call. */
|
||||
state->read_error_warning_shown = true;
|
||||
state->transfer.read_error_warning_shown = true;
|
||||
}
|
||||
|
||||
orig_offset = (off_t) lseek(fd, 0, SEEK_CUR);
|
||||
@@ -493,7 +497,7 @@ static int pv__transfer_read(pvstate_t state, int fd, bool *eof_in, bool *eof_ou
|
||||
/*@+compdef@ */
|
||||
/* splint - see previous pv_current_file_name() calls. */
|
||||
*eof_in = true;
|
||||
if (state->write_position >= state->read_position) {
|
||||
if (state->transfer.write_position >= state->transfer.read_position) {
|
||||
*eof_out = true;
|
||||
}
|
||||
return 1;
|
||||
@@ -504,13 +508,13 @@ static int pv__transfer_read(pvstate_t state, int fd, bool *eof_in, bool *eof_ou
|
||||
* otherwise start small and ramp up based on the number of errors
|
||||
* in a row.
|
||||
*/
|
||||
if (state->error_skip_block > 0) {
|
||||
amount_to_skip = state->error_skip_block;
|
||||
if (state->control.error_skip_block > 0) {
|
||||
amount_to_skip = state->control.error_skip_block;
|
||||
} else {
|
||||
if (state->read_errors_in_a_row < 10) {
|
||||
amount_to_skip = (off_t) (state->read_errors_in_a_row < 5 ? 1 : 2);
|
||||
} else if (state->read_errors_in_a_row < 20) {
|
||||
unsigned int shift_by = (unsigned int) (state->read_errors_in_a_row - 10);
|
||||
if (state->transfer.read_errors_in_a_row < 10) {
|
||||
amount_to_skip = (off_t) (state->transfer.read_errors_in_a_row < 5 ? 1 : 2);
|
||||
} else if (state->transfer.read_errors_in_a_row < 20) {
|
||||
unsigned int shift_by = (unsigned int) (state->transfer.read_errors_in_a_row - 10);
|
||||
amount_to_skip = (off_t) (1 << shift_by);
|
||||
} else {
|
||||
amount_to_skip = 512;
|
||||
@@ -581,9 +585,9 @@ static int pv__transfer_read(pvstate_t state, int fd, bool *eof_in, bool *eof_ou
|
||||
* of the transfer buffer, and update the buffer position.
|
||||
*/
|
||||
if (amount_skipped > 0) {
|
||||
memset(state->transfer_buffer + state->read_position, 0, (size_t) amount_skipped);
|
||||
state->read_position += amount_skipped;
|
||||
if (state->skip_errors < 2) {
|
||||
memset(state->transfer.transfer_buffer + state->transfer.read_position, 0, (size_t) amount_skipped);
|
||||
state->transfer.read_position += amount_skipped;
|
||||
if (state->control.skip_errors < 2) {
|
||||
/*@-compdef@ */
|
||||
pv_error(state, "%s: %s: %ld - %ld (%ld %s)",
|
||||
pv_current_file_name(state),
|
||||
@@ -597,7 +601,7 @@ static int pv__transfer_read(pvstate_t state, int fd, bool *eof_in, bool *eof_ou
|
||||
* Failed to skip - mark file as ended.
|
||||
*/
|
||||
*eof_in = true;
|
||||
if (state->write_position >= state->read_position) {
|
||||
if (state->transfer.write_position >= state->transfer.read_position) {
|
||||
*eof_out = true;
|
||||
}
|
||||
}
|
||||
@@ -607,47 +611,48 @@ static int pv__transfer_read(pvstate_t state, int fd, bool *eof_in, bool *eof_ou
|
||||
|
||||
|
||||
/*
|
||||
* Write state->to_write bytes of data from the transfer buffer to stdout.
|
||||
* Write state->transfer.to_write bytes of data from the transfer buffer to stdout.
|
||||
* Returns zero if there was a transient error and we need to return 0 from
|
||||
* pv_transfer, otherwise returns 1.
|
||||
*
|
||||
* Updates state->write_position by moving it on by the number of bytes
|
||||
* written; adds the number of bytes written to state->written; sets
|
||||
* Updates state->transfer.write_position by moving it on by the number of bytes
|
||||
* written; adds the number of bytes written to state->transfer.written; sets
|
||||
* *eof_out to true, on stdout EOF, or when the write position catches up
|
||||
* with the read position AND *eof_in is true (meaning we've reached the end
|
||||
* of data).
|
||||
*
|
||||
* On error, sets *eof_out to true, sets state->written to -1, and updates
|
||||
* state->exit_status.
|
||||
* On error, sets *eof_out to true, sets state->transfer.written to -1, and updates
|
||||
* state->status.exit_status.
|
||||
*
|
||||
* If state->discard_input is true, does not actually write anything.
|
||||
* If state->control.discard_input is true, does not actually write anything.
|
||||
*/
|
||||
static int pv__transfer_write(pvstate_t state, bool *eof_in, bool *eof_out, long *lineswritten)
|
||||
{
|
||||
ssize_t nwritten;
|
||||
|
||||
if (NULL == state->transfer_buffer) {
|
||||
if (NULL == state->transfer.transfer_buffer) {
|
||||
pv_error(state, "%s", _("no transfer buffer allocated"));
|
||||
state->exit_status |= 64;
|
||||
state->status.exit_status |= 64;
|
||||
*eof_out = true;
|
||||
state->written = -1;
|
||||
state->transfer.written = -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
nwritten = 0;
|
||||
|
||||
if (state->discard_input) {
|
||||
nwritten = state->to_write;
|
||||
} else if (state->to_write > 0) {
|
||||
if (state->control.discard_input) {
|
||||
nwritten = state->transfer.to_write;
|
||||
} else if (state->transfer.to_write > 0) {
|
||||
if (signal(SIGALRM, SIG_IGN) == SIG_ERR) {
|
||||
pv_error(state, "%s: %s", _("failed to set alarm signal handler"), strerror(errno));
|
||||
} else {
|
||||
(void) alarm(1);
|
||||
}
|
||||
nwritten = pv__transfer_write_repeated(STDOUT_FILENO,
|
||||
state->transfer_buffer +
|
||||
state->write_position, (size_t) (state->to_write),
|
||||
state->sync_after_write);
|
||||
state->transfer.transfer_buffer +
|
||||
state->transfer.write_position,
|
||||
(size_t) (state->transfer.to_write),
|
||||
state->control.sync_after_write);
|
||||
(void) alarm(0);
|
||||
}
|
||||
|
||||
@@ -661,20 +666,21 @@ static int pv__transfer_write(pvstate_t state, bool *eof_in, bool *eof_out, long
|
||||
/*
|
||||
* Write returned >0 - data successfully written.
|
||||
*/
|
||||
if ((state->linemode) && (lineswritten != NULL)) {
|
||||
if ((state->control.linemode) && (lineswritten != NULL)) {
|
||||
char separator;
|
||||
char *ptr;
|
||||
long lines = 0;
|
||||
|
||||
if (state->null_terminated_lines) {
|
||||
if (state->control.null_terminated_lines) {
|
||||
separator = '\0';
|
||||
} else {
|
||||
separator = '\n';
|
||||
}
|
||||
|
||||
ptr = (char *) (state->transfer_buffer + state->write_position - 1);
|
||||
ptr = (char *) (state->transfer.transfer_buffer + state->transfer.write_position - 1);
|
||||
for (ptr++;
|
||||
ptr - (char *) state->transfer_buffer - state->write_position < (size_t) nwritten; ptr++) {
|
||||
ptr - (char *) state->transfer.transfer_buffer - state->transfer.write_position <
|
||||
(size_t) nwritten; ptr++) {
|
||||
if (*ptr == separator)
|
||||
++lines;
|
||||
}
|
||||
@@ -682,37 +688,38 @@ static int pv__transfer_write(pvstate_t state, bool *eof_in, bool *eof_out, long
|
||||
*lineswritten += lines;
|
||||
}
|
||||
|
||||
state->write_position += nwritten;
|
||||
state->written += nwritten;
|
||||
state->transfer.write_position += nwritten;
|
||||
state->transfer.written += nwritten;
|
||||
|
||||
/*
|
||||
* If we're monitoring the output, update our copy of the
|
||||
* last few bytes we've written.
|
||||
*/
|
||||
if (((state->components_used & PV_DISPLAY_OUTPUTBUF) != 0)
|
||||
if (((state->display.components_used & PV_DISPLAY_OUTPUTBUF) != 0)
|
||||
&& (nwritten > 0)) {
|
||||
size_t new_portion_length, old_portion_length;
|
||||
|
||||
new_portion_length = (size_t) nwritten;
|
||||
if (new_portion_length > state->lastoutput_length)
|
||||
new_portion_length = state->lastoutput_length;
|
||||
if (new_portion_length > state->display.lastoutput_length)
|
||||
new_portion_length = state->display.lastoutput_length;
|
||||
|
||||
old_portion_length = state->lastoutput_length - new_portion_length;
|
||||
old_portion_length = state->display.lastoutput_length - new_portion_length;
|
||||
|
||||
/*
|
||||
* Make room for the new portion.
|
||||
*/
|
||||
if (old_portion_length > 0) {
|
||||
memmove(state->lastoutput_buffer,
|
||||
state->lastoutput_buffer + new_portion_length, old_portion_length);
|
||||
memmove(state->display.lastoutput_buffer,
|
||||
state->display.lastoutput_buffer + new_portion_length, old_portion_length);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy the new data in.
|
||||
*/
|
||||
memcpy(state->lastoutput_buffer + /* flawfinder: ignore */
|
||||
memcpy(state->display.lastoutput_buffer + /* flawfinder: ignore */
|
||||
old_portion_length,
|
||||
state->transfer_buffer + state->write_position - new_portion_length, new_portion_length);
|
||||
state->transfer.transfer_buffer + state->transfer.write_position - new_portion_length,
|
||||
new_portion_length);
|
||||
/*
|
||||
* flawfinder rationale: calculations above ensure
|
||||
* that old_portion_length + new_portion_length is
|
||||
@@ -731,9 +738,9 @@ static int pv__transfer_write(pvstate_t state, bool *eof_in, bool *eof_out, long
|
||||
* EOF, set eof_out as well to indicate that we've written
|
||||
* everything for this input file.
|
||||
*/
|
||||
if (state->write_position >= state->read_position) {
|
||||
state->write_position = 0;
|
||||
state->read_position = 0;
|
||||
if (state->transfer.write_position >= state->transfer.read_position) {
|
||||
state->transfer.write_position = 0;
|
||||
state->transfer.read_position = 0;
|
||||
if (*eof_in)
|
||||
*eof_out = true;
|
||||
}
|
||||
@@ -766,9 +773,9 @@ static int pv__transfer_write(pvstate_t state, bool *eof_in, bool *eof_out, long
|
||||
}
|
||||
|
||||
pv_error(state, "%s: %s", _("write failed"), strerror(errno));
|
||||
state->exit_status |= 16;
|
||||
state->status.exit_status |= 16;
|
||||
*eof_out = true;
|
||||
state->written = -1;
|
||||
state->transfer.written = -1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -841,13 +848,13 @@ static char *pv__allocate_aligned_buffer(int fd, size_t target_size)
|
||||
|
||||
/*
|
||||
* Transfer some data from "fd" to standard output, timing out after 9/100
|
||||
* of a second. If state->rate_limit is >0, and/or "allowed" is >0, only up
|
||||
* of a second. If state->control.rate_limit is >0, and/or "allowed" is >0, only up
|
||||
* to "allowed" bytes can be written. The variables that "eof_in" and
|
||||
* "eof_out" point to are used to flag that we've finished reading and
|
||||
* writing respectively.
|
||||
*
|
||||
* Returns the number of bytes written, or negative on error (in which case
|
||||
* state->exit_status is updated). In line mode, the number of lines written
|
||||
* state->status.exit_status is updated). In line mode, the number of lines written
|
||||
* will be put into *lineswritten.
|
||||
*/
|
||||
ssize_t pv_transfer(pvstate_t state, int fd, bool *eof_in, bool *eof_out, off_t allowed, long *lineswritten)
|
||||
@@ -864,9 +871,9 @@ ssize_t pv_transfer(pvstate_t state, int fd, bool *eof_in, bool *eof_out, off_t
|
||||
* Set or clear O_DIRECT on the input and output file descriptors,
|
||||
* if the setting has changed.
|
||||
*/
|
||||
if (state->direct_io_changed) {
|
||||
if (state->control.direct_io_changed) {
|
||||
if (!(*eof_in)) {
|
||||
if (0 != fcntl(fd, F_SETFL, (state->direct_io ? O_DIRECT : 0) | fcntl(fd, F_GETFL))) {
|
||||
if (0 != fcntl(fd, F_SETFL, (state->control.direct_io ? O_DIRECT : 0) | fcntl(fd, F_GETFL))) {
|
||||
/*@-compdef@ */
|
||||
debug("%s: %s: %s", pv_current_file_name(state), "fcntl", strerror(errno));
|
||||
/*@+compdef@ */
|
||||
@@ -875,11 +882,11 @@ ssize_t pv_transfer(pvstate_t state, int fd, bool *eof_in, bool *eof_out, off_t
|
||||
}
|
||||
if (!(*eof_out)) {
|
||||
if (0 != fcntl(STDOUT_FILENO, F_SETFL,
|
||||
(state->direct_io ? O_DIRECT : 0) | fcntl(STDOUT_FILENO, F_GETFL))) {
|
||||
(state->control.direct_io ? O_DIRECT : 0) | fcntl(STDOUT_FILENO, F_GETFL))) {
|
||||
debug("%s: %s: %s", "(stdout)", "fcntl", strerror(errno));
|
||||
}
|
||||
}
|
||||
state->direct_io_changed = false;
|
||||
state->control.direct_io_changed = false;
|
||||
}
|
||||
#endif /* O_DIRECT */
|
||||
|
||||
@@ -887,24 +894,25 @@ ssize_t pv_transfer(pvstate_t state, int fd, bool *eof_in, bool *eof_out, off_t
|
||||
* Reinitialise the error skipping variables if the file descriptor
|
||||
* has changed since the last time we were called.
|
||||
*/
|
||||
if (fd != state->last_read_skip_fd) {
|
||||
state->last_read_skip_fd = fd;
|
||||
state->read_errors_in_a_row = 0;
|
||||
state->read_error_warning_shown = false;
|
||||
if (fd != state->transfer.last_read_skip_fd) {
|
||||
state->transfer.last_read_skip_fd = fd;
|
||||
state->transfer.read_errors_in_a_row = 0;
|
||||
state->transfer.read_error_warning_shown = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a new buffer, aligned appropriately for the input file
|
||||
* (important if using O_DIRECT).
|
||||
*/
|
||||
if (NULL == state->transfer_buffer) {
|
||||
state->transfer_buffer = pv__allocate_aligned_buffer(fd, state->target_buffer_size + 32);
|
||||
if (NULL == state->transfer_buffer) {
|
||||
if (NULL == state->transfer.transfer_buffer) {
|
||||
state->transfer.transfer_buffer =
|
||||
pv__allocate_aligned_buffer(fd, state->control.target_buffer_size + 32);
|
||||
if (NULL == state->transfer.transfer_buffer) {
|
||||
pv_error(state, "%s: %s", _("buffer allocation failed"), strerror(errno));
|
||||
state->exit_status |= 64;
|
||||
state->status.exit_status |= 64;
|
||||
return -1;
|
||||
}
|
||||
state->buffer_size = state->target_buffer_size;
|
||||
state->transfer.buffer_size = state->control.target_buffer_size;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -914,37 +922,37 @@ ssize_t pv_transfer(pvstate_t state, int fd, bool *eof_in, bool *eof_out, off_t
|
||||
* memory) because the buffer may need to be aligned for O_DIRECT,
|
||||
* and we can't realloc() an aligned buffer.
|
||||
*/
|
||||
if (state->buffer_size < state->target_buffer_size) {
|
||||
if (state->transfer.buffer_size < state->control.target_buffer_size) {
|
||||
char *newptr;
|
||||
newptr = pv__allocate_aligned_buffer(fd, state->target_buffer_size + 32);
|
||||
newptr = pv__allocate_aligned_buffer(fd, state->control.target_buffer_size + 32);
|
||||
if (NULL == newptr) {
|
||||
/*
|
||||
* Reset target if realloc failed so we don't keep
|
||||
* trying to realloc over and over.
|
||||
*/
|
||||
debug("realloc: %s", strerror(errno));
|
||||
state->target_buffer_size = state->buffer_size;
|
||||
state->control.target_buffer_size = state->transfer.buffer_size;
|
||||
} else {
|
||||
debug("%s: %ld", "buffer resized", state->buffer_size);
|
||||
debug("%s: %ld", "buffer resized", state->transfer.buffer_size);
|
||||
/*
|
||||
* Copy the old buffer contents into the new buffer,
|
||||
* and free the old one.
|
||||
*/
|
||||
if (state->buffer_size > 0) {
|
||||
memcpy(newptr, state->transfer_buffer, state->buffer_size); /* flawfinder: ignore */
|
||||
if (state->transfer.buffer_size > 0) {
|
||||
memcpy(newptr, state->transfer.transfer_buffer, state->transfer.buffer_size); /* flawfinder: ignore */
|
||||
}
|
||||
/*
|
||||
* flawfinder rationale: number of bytes copied is
|
||||
* definitely always smaller than the new buffer
|
||||
* size.
|
||||
*/
|
||||
free(state->transfer_buffer);
|
||||
state->transfer_buffer = newptr;
|
||||
state->buffer_size = state->target_buffer_size;
|
||||
free(state->transfer.transfer_buffer);
|
||||
state->transfer.transfer_buffer = newptr;
|
||||
state->transfer.buffer_size = state->control.target_buffer_size;
|
||||
}
|
||||
}
|
||||
|
||||
if ((state->linemode) && (lineswritten != NULL))
|
||||
if ((state->control.linemode) && (lineswritten != NULL))
|
||||
*lineswritten = 0;
|
||||
|
||||
if ((*eof_in) && (*eof_out))
|
||||
@@ -957,7 +965,7 @@ ssize_t pv_transfer(pvstate_t state, int fd, bool *eof_in, bool *eof_out, off_t
|
||||
* If the input file is not at EOF and there's room in the buffer,
|
||||
* look for incoming data from it.
|
||||
*/
|
||||
if ((!(*eof_in)) && (state->read_position < state->buffer_size)) {
|
||||
if ((!(*eof_in)) && (state->transfer.read_position < state->transfer.buffer_size)) {
|
||||
check_read_fd = fd;
|
||||
}
|
||||
|
||||
@@ -967,10 +975,10 @@ ssize_t pv_transfer(pvstate_t state, int fd, bool *eof_in, bool *eof_out, off_t
|
||||
* is >0, then this puts an upper limit on how much we're allowed to
|
||||
* write.
|
||||
*/
|
||||
state->to_write = (ssize_t) (state->read_position - state->write_position);
|
||||
if ((state->rate_limit > 0) || (allowed > 0)) {
|
||||
if ((off_t) (state->to_write) > allowed) {
|
||||
state->to_write = (ssize_t) allowed;
|
||||
state->transfer.to_write = (ssize_t) (state->transfer.read_position - state->transfer.write_position);
|
||||
if ((state->control.rate_limit > 0) || (allowed > 0)) {
|
||||
if ((off_t) (state->transfer.to_write) > allowed) {
|
||||
state->transfer.to_write = (ssize_t) allowed;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -978,7 +986,7 @@ ssize_t pv_transfer(pvstate_t state, int fd, bool *eof_in, bool *eof_out, off_t
|
||||
* If we don't think we've finished writing and there's anything
|
||||
* we're allowed to write, look for the stdout becoming writable.
|
||||
*/
|
||||
if ((!(*eof_out)) && (state->to_write > 0)) {
|
||||
if ((!(*eof_out)) && (state->transfer.to_write > 0)) {
|
||||
check_write_fd = STDOUT_FILENO;
|
||||
}
|
||||
|
||||
@@ -1002,18 +1010,18 @@ ssize_t pv_transfer(pvstate_t state, int fd, bool *eof_in, bool *eof_out, off_t
|
||||
/*@+compdef@ */
|
||||
/* splint - see previous pv_current_file_name() calls. */
|
||||
|
||||
state->exit_status |= 16;
|
||||
state->status.exit_status |= 16;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
state->written = 0;
|
||||
state->transfer.written = 0;
|
||||
|
||||
/*
|
||||
* If there is data to read, try to read some in. Return early if
|
||||
* there was a transient read error.
|
||||
*
|
||||
* NB this can update state->written because of splice().
|
||||
* NB this can update state->transfer.written because of splice().
|
||||
*/
|
||||
if (ready_to_read) {
|
||||
if (pv__transfer_read(state, fd, eof_in, eof_out, allowed) == 0)
|
||||
@@ -1024,15 +1032,15 @@ ssize_t pv_transfer(pvstate_t state, int fd, bool *eof_in, bool *eof_out, off_t
|
||||
* In line mode, only write up to and including the last newline,
|
||||
* so that we're writing output line-by-line.
|
||||
*/
|
||||
if ((state->to_write > 0) && (state->linemode) && !(state->null_terminated_lines)) {
|
||||
if ((state->transfer.to_write > 0) && (state->control.linemode) && !(state->control.null_terminated_lines)) {
|
||||
char *start;
|
||||
char *end;
|
||||
|
||||
start = (char *) (state->transfer_buffer + state->write_position);
|
||||
end = pv_memrchr(start, (int) '\n', (size_t) (state->to_write));
|
||||
start = (char *) (state->transfer.transfer_buffer + state->transfer.write_position);
|
||||
end = pv_memrchr(start, (int) '\n', (size_t) (state->transfer.to_write));
|
||||
|
||||
if (NULL != end) {
|
||||
state->to_write = (ssize_t) ((end - start) + 1);
|
||||
state->transfer.to_write = (ssize_t) ((end - start) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1043,10 +1051,10 @@ ssize_t pv_transfer(pvstate_t state, int fd, bool *eof_in, bool *eof_out, off_t
|
||||
*/
|
||||
if (ready_to_write
|
||||
#ifdef HAVE_SPLICE
|
||||
&& (!state->splice_used)
|
||||
&& (!state->transfer.splice_used)
|
||||
#endif /* HAVE_SPLICE */
|
||||
&& (state->read_position > state->write_position)
|
||||
&& (state->to_write > 0)
|
||||
&& (state->transfer.read_position > state->transfer.write_position)
|
||||
&& (state->transfer.to_write > 0)
|
||||
&& (NULL != lineswritten)) {
|
||||
if (pv__transfer_write(state, eof_in, eof_out, lineswritten) == 0)
|
||||
return 0;
|
||||
@@ -1056,21 +1064,22 @@ ssize_t pv_transfer(pvstate_t state, int fd, bool *eof_in, bool *eof_out, off_t
|
||||
* Rotate the written bytes out of the buffer so that it can be
|
||||
* filled up completely by the next read.
|
||||
*/
|
||||
if (state->write_position > 0) {
|
||||
if (state->write_position < state->read_position) {
|
||||
memmove(state->transfer_buffer,
|
||||
state->transfer_buffer +
|
||||
state->write_position, state->read_position - state->write_position);
|
||||
state->read_position -= state->write_position;
|
||||
state->write_position = 0;
|
||||
if (state->transfer.write_position > 0) {
|
||||
if (state->transfer.write_position < state->transfer.read_position) {
|
||||
memmove(state->transfer.transfer_buffer,
|
||||
state->transfer.transfer_buffer +
|
||||
state->transfer.write_position,
|
||||
state->transfer.read_position - state->transfer.write_position);
|
||||
state->transfer.read_position -= state->transfer.write_position;
|
||||
state->transfer.write_position = 0;
|
||||
} else {
|
||||
state->write_position = 0;
|
||||
state->read_position = 0;
|
||||
state->transfer.write_position = 0;
|
||||
state->transfer.read_position = 0;
|
||||
}
|
||||
}
|
||||
#endif /* MAXIMISE_BUFFER_FILL */
|
||||
|
||||
return state->written;
|
||||
return state->transfer.written;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
||||
+13
-13
@@ -385,8 +385,8 @@ int pv_watchpid_scanfds(pvstate_t state, pvstate_t pristine,
|
||||
*array_length_ptr = array_length;
|
||||
|
||||
for (check_idx = 0; check_idx < array_length; check_idx++) {
|
||||
state_array[check_idx].name = info_array[check_idx].display_name;
|
||||
state_array[check_idx].reparse_display = 1;
|
||||
state_array[check_idx].control.name = info_array[check_idx].display_name;
|
||||
state_array[check_idx].flag.reparse_display = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -427,31 +427,31 @@ int pv_watchpid_scanfds(pvstate_t state, pvstate_t pristine,
|
||||
info_array[use_idx].watch_fd = -1;
|
||||
}
|
||||
|
||||
state_array[use_idx].size = info_array[use_idx].size;
|
||||
if (state_array[use_idx].size < 1) {
|
||||
state_array[use_idx].control.size = info_array[use_idx].size;
|
||||
if (state_array[use_idx].control.size < 1) {
|
||||
char *fmt;
|
||||
while (NULL != (fmt = strstr(state_array[use_idx].default_format, "%e"))) {
|
||||
while (NULL != (fmt = strstr(state_array[use_idx].control.default_format, "%e"))) {
|
||||
debug("%s", "zero size - removing ETA");
|
||||
/* strlen-1 here to include trailing NUL */
|
||||
memmove(fmt, fmt + 2, strlen(fmt) - 1);
|
||||
state_array[use_idx].reparse_display = 1;
|
||||
state_array[use_idx].flag.reparse_display = 1;
|
||||
}
|
||||
}
|
||||
|
||||
state_array[use_idx].name = info_array[use_idx].display_name;
|
||||
state_array[use_idx].control.name = info_array[use_idx].display_name;
|
||||
|
||||
pv_watchpid_setname(state, &(info_array[use_idx]));
|
||||
|
||||
state_array[use_idx].reparse_display = 1;
|
||||
state_array[use_idx].flag.reparse_display = 1;
|
||||
|
||||
pv_elapsedtime_read(&(info_array[use_idx].start_time));
|
||||
|
||||
state_array[use_idx].initial_offset = 0;
|
||||
state_array[use_idx].display.initial_offset = 0;
|
||||
info_array[use_idx].position = 0;
|
||||
|
||||
position_now = pv_watchfd_position(&(info_array[use_idx]));
|
||||
if (position_now >= 0) {
|
||||
state_array[use_idx].initial_offset = position_now;
|
||||
state_array[use_idx].display.initial_offset = position_now;
|
||||
info_array[use_idx].position = position_now;
|
||||
}
|
||||
}
|
||||
@@ -482,15 +482,15 @@ void pv_watchpid_setname(pvstate_t state, pvwatchfd_t info)
|
||||
memset(info->display_name, 0, PV_SIZEOF_DISPLAY_NAME);
|
||||
|
||||
path_length = strlen(info->file_fdpath);
|
||||
cwd_length = strlen(state->cwd);
|
||||
cwd_length = strlen(state->status.cwd);
|
||||
if (cwd_length > 0 && path_length > cwd_length) {
|
||||
if (0 == strncmp(info->file_fdpath, state->cwd, cwd_length)) {
|
||||
if (0 == strncmp(info->file_fdpath, state->status.cwd, cwd_length)) {
|
||||
file_fdpath += cwd_length + 1;
|
||||
path_length -= cwd_length + 1;
|
||||
}
|
||||
}
|
||||
|
||||
max_display_length = (state->width / 2) - 6;
|
||||
max_display_length = (state->control.width / 2) - 6;
|
||||
if (max_display_length >= path_length) {
|
||||
(void) pv_snprintf(info->display_name,
|
||||
PV_SIZEOF_DISPLAY_NAME, "%4d:%.498s", info->watch_fd, file_fdpath);
|
||||
|
||||
Reference in New Issue
Block a user