Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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

+20-18
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

+7-7
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

+13-9
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

+1-1
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)