Skip to content

Commit 9f44d71

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 29bd2cb commit 9f44d71

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
@@ -143,7 +143,8 @@ static PQExpBuffer recoveryconfcontents = NULL;
143143
/* Function headers */
144144
static void usage(void);
145145
static void verify_dir_is_empty_or_create(char *dirname, bool *created, bool *found);
146-
static void progress_report(int tablespacenum, const char *filename, bool force);
146+
static void progress_report(int tablespacenum, const char *filename, bool force,
147+
bool finished);
147148

148149
static void ReceiveTarFile(PGconn *conn, PGresult *res, int rownum);
149150
static void ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum);
@@ -706,11 +707,15 @@ verify_dir_is_empty_or_create(char *dirname, bool *created, bool *found)
706707
* Print a progress report based on the global variables. If verbose output
707708
* is enabled, also print the current file name.
708709
*
709-
* Progress report is written at maximum once per second, unless the
710-
* force parameter is set to true.
710+
* Progress report is written at maximum once per second, unless the force
711+
* parameter is set to true.
712+
*
713+
* If finished is set to true, this is the last progress report. The cursor
714+
* is moved to the next line.
711715
*/
712716
static void
713-
progress_report(int tablespacenum, const char *filename, bool force)
717+
progress_report(int tablespacenum, const char *filename,
718+
bool force, bool finished)
714719
{
715720
int percent;
716721
char totaldone_str[32];
@@ -721,7 +726,7 @@ progress_report(int tablespacenum, const char *filename, bool force)
721726
return;
722727

723728
now = time(NULL);
724-
if (now == last_progress_report && !force)
729+
if (now == last_progress_report && !force && !finished)
725730
return; /* Max once per second */
726731

727732
last_progress_report = now;
@@ -792,10 +797,11 @@ progress_report(int tablespacenum, const char *filename, bool force)
792797
totaldone_str, totalsize_str, percent,
793798
tablespacenum, tablespacecount);
794799

795-
if (isatty(fileno(stderr)))
796-
fprintf(stderr, "\r");
797-
else
798-
fprintf(stderr, "\n");
800+
/*
801+
* Stay on the same line if reporting to a terminal and we're not done
802+
* yet.
803+
*/
804+
fprintf(stderr, (!finished && isatty(fileno(stderr))) ? "\r" : "\n");
799805
}
800806

801807
static int32
@@ -1355,9 +1361,9 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
13551361
}
13561362
}
13571363
totaldone += r;
1358-
progress_report(rownum, filename, false);
1364+
progress_report(rownum, filename, false, false);
13591365
} /* while (1) */
1360-
progress_report(rownum, filename, true);
1366+
progress_report(rownum, filename, true, false);
13611367

13621368
if (copybuf != NULL)
13631369
PQfreemem(copybuf);
@@ -1614,7 +1620,7 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum)
16141620
exit(1);
16151621
}
16161622
totaldone += r;
1617-
progress_report(rownum, filename, false);
1623+
progress_report(rownum, filename, false, false);
16181624

16191625
current_len_left -= r;
16201626
if (current_len_left == 0 && current_padding == 0)
@@ -1630,7 +1636,7 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum)
16301636
}
16311637
} /* continuing data in existing file */
16321638
} /* loop over all data blocks */
1633-
progress_report(rownum, filename, true);
1639+
progress_report(rownum, filename, true, false);
16341640

16351641
if (file != NULL)
16361642
{
@@ -2011,11 +2017,7 @@ BaseBackup(void)
20112017
} /* Loop over all tablespaces */
20122018

20132019
if (showprogress)
2014-
{
2015-
progress_report(PQntuples(res), NULL, true);
2016-
if (isatty(fileno(stderr)))
2017-
fprintf(stderr, "\n"); /* Need to move to next line */
2018-
}
2020+
progress_report(PQntuples(res), NULL, true, true);
20192021

20202022
PQclear(res);
20212023

src/bin/pg_checksums/pg_checksums.c

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

136136
now = time(NULL);
137-
if (now == last_progress_report && !force)
137+
if (now == last_progress_report && !finished)
138138
return; /* Max once per second */
139139

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

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

168171
static bool
@@ -623,10 +626,7 @@ main(int argc, char *argv[])
623626
(void) scan_directory(DataDir, "pg_tblspc", false);
624627

625628
if (showprogress)
626-
{
627629
progress_report(true);
628-
fprintf(stderr, "\n"); /* Need to move to next line */
629-
}
630630

631631
printf(_("Checksum operation completed\n"));
632632
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
@@ -359,7 +359,6 @@ main(int argc, char **argv)
359359
executeFileMap();
360360

361361
progress_report(true);
362-
printf("\n");
363362

364363
if (showprogress)
365364
pg_log_info("creating backup label and updating control file");
@@ -452,11 +451,14 @@ sanityChecks(void)
452451
/*
453452
* Print a progress report based on the fetch_size and fetch_done variables.
454453
*
455-
* Progress report is written at maximum once per second, unless the
456-
* force parameter is set to true.
454+
* Progress report is written at maximum once per second, except that the
455+
* last progress report is always printed.
456+
*
457+
* If finished is set to true, this is the last progress report. The cursor
458+
* is moved to the next line.
457459
*/
458460
void
459-
progress_report(bool force)
461+
progress_report(bool finished)
460462
{
461463
static pg_time_t last_progress_report = 0;
462464
int percent;
@@ -468,7 +470,7 @@ progress_report(bool force)
468470
return;
469471

470472
now = time(NULL);
471-
if (now == last_progress_report && !force)
473+
if (now == last_progress_report && !finished)
472474
return; /* Max once per second */
473475

474476
last_progress_report = now;
@@ -498,10 +500,12 @@ progress_report(bool force)
498500
fprintf(stderr, _("%*s/%s kB (%d%%) copied"),
499501
(int) strlen(fetch_size_str), fetch_done_str, fetch_size_str,
500502
percent);
501-
if (isatty(fileno(stderr)))
502-
fprintf(stderr, "\r");
503-
else
504-
fprintf(stderr, "\n");
503+
504+
/*
505+
* Stay on the same line if reporting to a terminal and we're not done
506+
* yet.
507+
*/
508+
fprintf(stderr, (!finished && isatty(fileno(stderr))) ? "\r" : "\n");
505509
}
506510

507511
/*

src/bin/pg_rewind/pg_rewind.h

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

5151
/* in pg_rewind.c */
52-
extern void progress_report(bool force);
52+
extern void progress_report(bool finished);
5353

5454
/* in timeline.c */
5555
extern TimeLineHistoryEntry *rewind_parseTimeLineHistory(char *buffer,

0 commit comments

Comments
 (0)