Skip to content

Commit 5ca1798

Browse files
committed
Fix printing last progress report line in client programs.
A number of client programs have a "--progress" option that when printing to a TTY, updates the current line by printing a '\r' and overwriting it. After the last line, '\n' needs to be printed to move the cursor to the next line. pg_basebackup and pgbench got this right, but pg_rewind and pg_checksums were slightly wrong. pg_rewind printed the newline to stdout instead of stderr, and pg_checksums printed the newline even when not printing to a TTY. Fix them, and also add a 'finished' argument to pg_basebackup's progress_report() function, to keep it consistent with the other programs. Backpatch to v12. pg_rewind's newline was broken with the logging changes in commit cc8d415 in v12, and pg_checksums was introduced in v12. Discussion: https://www.postgresql.org/message-id/82b539e5-ae33-34b0-1aee-22b3379fd3eb@iki.fi
1 parent 3424c6b commit 5ca1798

File tree

4 files changed

+41
-35
lines changed

4 files changed

+41
-35
lines changed

src/bin/pg_basebackup/pg_basebackup.c

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,8 @@ static PQExpBuffer recoveryconfcontents = NULL;
188188
/* Function headers */
189189
static void usage(void);
190190
static void verify_dir_is_empty_or_create(char *dirname, bool *created, bool *found);
191-
static void progress_report(int tablespacenum, const char *filename, bool force);
191+
static void progress_report(int tablespacenum, const char *filename, bool force,
192+
bool finished);
192193

193194
static void ReceiveTarFile(PGconn *conn, PGresult *res, int rownum);
194195
static void ReceiveTarCopyChunk(size_t r, char *copybuf, void *callback_data);
@@ -765,11 +766,15 @@ verify_dir_is_empty_or_create(char *dirname, bool *created, bool *found)
765766
* Print a progress report based on the global variables. If verbose output
766767
* is enabled, also print the current file name.
767768
*
768-
* Progress report is written at maximum once per second, unless the
769-
* force parameter is set to true.
769+
* Progress report is written at maximum once per second, unless the force
770+
* parameter is set to true.
771+
*
772+
* If finished is set to true, this is the last progress report. The cursor
773+
* is moved to the next line.
770774
*/
771775
static void
772-
progress_report(int tablespacenum, const char *filename, bool force)
776+
progress_report(int tablespacenum, const char *filename,
777+
bool force, bool finished)
773778
{
774779
int percent;
775780
char totaldone_str[32];
@@ -780,7 +785,7 @@ progress_report(int tablespacenum, const char *filename, bool force)
780785
return;
781786

782787
now = time(NULL);
783-
if (now == last_progress_report && !force)
788+
if (now == last_progress_report && !force && !finished)
784789
return; /* Max once per second */
785790

786791
last_progress_report = now;
@@ -851,10 +856,11 @@ progress_report(int tablespacenum, const char *filename, bool force)
851856
totaldone_str, totalsize_str, percent,
852857
tablespacenum, tablespacecount);
853858

854-
if (isatty(fileno(stderr)))
855-
fprintf(stderr, "\r");
856-
else
857-
fprintf(stderr, "\n");
859+
/*
860+
* Stay on the same line if reporting to a terminal and we're not done
861+
* yet.
862+
*/
863+
fprintf(stderr, (!finished && isatty(fileno(stderr))) ? "\r" : "\n");
858864
}
859865

860866
static int32
@@ -1277,7 +1283,7 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
12771283
}
12781284
}
12791285

1280-
progress_report(rownum, state.filename, true);
1286+
progress_report(rownum, state.filename, true, false);
12811287

12821288
/*
12831289
* Do not sync the resulting tar file yet, all files are synced once at
@@ -1470,7 +1476,7 @@ ReceiveTarCopyChunk(size_t r, char *copybuf, void *callback_data)
14701476
}
14711477
}
14721478
totaldone += r;
1473-
progress_report(state->tablespacenum, state->filename, false);
1479+
progress_report(state->tablespacenum, state->filename, false, false);
14741480
}
14751481

14761482

@@ -1528,7 +1534,7 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum)
15281534
if (state.file)
15291535
fclose(state.file);
15301536

1531-
progress_report(rownum, state.filename, true);
1537+
progress_report(rownum, state.filename, true, false);
15321538

15331539
if (state.file != NULL)
15341540
{
@@ -1709,7 +1715,7 @@ ReceiveTarAndUnpackCopyChunk(size_t r, char *copybuf, void *callback_data)
17091715
exit(1);
17101716
}
17111717
totaldone += r;
1712-
progress_report(state->tablespacenum, state->filename, false);
1718+
progress_report(state->tablespacenum, state->filename, false, false);
17131719

17141720
state->current_len_left -= r;
17151721
if (state->current_len_left == 0 && state->current_padding == 0)
@@ -2027,11 +2033,7 @@ BaseBackup(void)
20272033
ReceiveBackupManifest(conn);
20282034

20292035
if (showprogress)
2030-
{
2031-
progress_report(PQntuples(res), NULL, true);
2032-
if (isatty(fileno(stderr)))
2033-
fprintf(stderr, "\n"); /* Need to move to next line */
2034-
}
2036+
progress_report(PQntuples(res), NULL, true, true);
20352037

20362038
PQclear(res);
20372039

src/bin/pg_checksums/pg_checksums.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ static const struct exclude_list_item skip[] = {
125125
* src/bin/pg_basebackup/pg_basebackup.c.
126126
*/
127127
static void
128-
progress_report(bool force)
128+
progress_report(bool finished)
129129
{
130130
int percent;
131131
char total_size_str[32];
@@ -135,7 +135,7 @@ progress_report(bool force)
135135
Assert(showprogress);
136136

137137
now = time(NULL);
138-
if (now == last_progress_report && !force)
138+
if (now == last_progress_report && !finished)
139139
return; /* Max once per second */
140140

141141
/* Save current time */
@@ -162,8 +162,11 @@ progress_report(bool force)
162162
(int) strlen(current_size_str), current_size_str, total_size_str,
163163
percent);
164164

165-
/* Stay on the same line if reporting to a terminal */
166-
fprintf(stderr, isatty(fileno(stderr)) ? "\r" : "\n");
165+
/*
166+
* Stay on the same line if reporting to a terminal and we're not done
167+
* yet.
168+
*/
169+
fprintf(stderr, (!finished && isatty(fileno(stderr))) ? "\r" : "\n");
167170
}
168171

169172
static bool
@@ -624,10 +627,7 @@ main(int argc, char *argv[])
624627
(void) scan_directory(DataDir, "pg_tblspc", false);
625628

626629
if (showprogress)
627-
{
628630
progress_report(true);
629-
fprintf(stderr, "\n"); /* Need to move to next line */
630-
}
631631

632632
printf(_("Checksum operation completed\n"));
633633
printf(_("Files scanned: %s\n"), psprintf(INT64_FORMAT, files));

src/bin/pg_rewind/pg_rewind.c

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,6 @@ main(int argc, char **argv)
422422
executeFileMap();
423423

424424
progress_report(true);
425-
printf("\n");
426425

427426
if (showprogress)
428427
pg_log_info("creating backup label and updating control file");
@@ -519,11 +518,14 @@ sanityChecks(void)
519518
/*
520519
* Print a progress report based on the fetch_size and fetch_done variables.
521520
*
522-
* Progress report is written at maximum once per second, unless the
523-
* force parameter is set to true.
521+
* Progress report is written at maximum once per second, except that the
522+
* last progress report is always printed.
523+
*
524+
* If finished is set to true, this is the last progress report. The cursor
525+
* is moved to the next line.
524526
*/
525527
void
526-
progress_report(bool force)
528+
progress_report(bool finished)
527529
{
528530
static pg_time_t last_progress_report = 0;
529531
int percent;
@@ -535,7 +537,7 @@ progress_report(bool force)
535537
return;
536538

537539
now = time(NULL);
538-
if (now == last_progress_report && !force)
540+
if (now == last_progress_report && !finished)
539541
return; /* Max once per second */
540542

541543
last_progress_report = now;
@@ -565,10 +567,12 @@ progress_report(bool force)
565567
fprintf(stderr, _("%*s/%s kB (%d%%) copied"),
566568
(int) strlen(fetch_size_str), fetch_done_str, fetch_size_str,
567569
percent);
568-
if (isatty(fileno(stderr)))
569-
fprintf(stderr, "\r");
570-
else
571-
fprintf(stderr, "\n");
570+
571+
/*
572+
* Stay on the same line if reporting to a terminal and we're not done
573+
* yet.
574+
*/
575+
fprintf(stderr, (!finished && isatty(fileno(stderr))) ? "\r" : "\n");
572576
}
573577

574578
/*

src/bin/pg_rewind/pg_rewind.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ extern XLogRecPtr readOneRecord(const char *datadir, XLogRecPtr ptr,
5353
int tliIndex, const char *restoreCommand);
5454

5555
/* in pg_rewind.c */
56-
extern void progress_report(bool force);
56+
extern void progress_report(bool finished);
5757

5858
/* in timeline.c */
5959
extern TimeLineHistoryEntry *rewind_parseTimeLineHistory(char *buffer,

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy