Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7fed801

Browse files
committed
Clean up inconsistent use of fflush().
More than twenty years ago (79fcde4), we hacked the postmaster to avoid a core-dump on systems that didn't support fflush(NULL). We've mostly, though not completely, hewed to that rule ever since. But such systems are surely gone in the wild, so in the spirit of cleaning out no-longer-needed portability hacks let's get rid of multiple per-file fflush() calls in favor of using fflush(NULL). Also, we were fairly inconsistent about whether to fflush() before popen() and system() calls. While we've received no bug reports about that, it seems likely that at least some of these call sites are at risk of odd behavior, such as error messages appearing in an unexpected order. Rather than expend a lot of brain cells figuring out which places are at hazard, let's just establish a uniform coding rule that we should fflush(NULL) before these calls. A no-op fflush() is surely of trivial cost compared to launching a sub-process via a shell; while if it's not a no-op then we likely need it. Discussion: https://postgr.es/m/[email protected]
1 parent 2079653 commit 7fed801

File tree

24 files changed

+52
-41
lines changed

24 files changed

+52
-41
lines changed

src/backend/access/transam/xlogarchive.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ RestoreArchivedFile(char *path, const char *xlogfname,
169169
/*
170170
* Copy xlog from archival storage to XLOGDIR
171171
*/
172+
fflush(NULL);
172173
pgstat_report_wait_start(WAIT_EVENT_RESTORE_COMMAND);
173174
rc = system(xlogRestoreCmd);
174175
pgstat_report_wait_end();
@@ -358,6 +359,7 @@ ExecuteRecoveryCommand(const char *command, const char *commandName,
358359
/*
359360
* execute the constructed command
360361
*/
362+
fflush(NULL);
361363
pgstat_report_wait_start(wait_event_info);
362364
rc = system(xlogRecoveryCmd);
363365
pgstat_report_wait_end();

src/backend/postmaster/fork_process.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,8 @@ fork_process(void)
3737

3838
/*
3939
* Flush stdio channels just before fork, to avoid double-output problems.
40-
* Ideally we'd use fflush(NULL) here, but there are still a few non-ANSI
41-
* stdio libraries out there (like SunOS 4.1.x) that coredump if we do.
42-
* Presently stdout and stderr are the only stdio output channels used by
43-
* the postmaster, so fflush'ing them should be sufficient.
4440
*/
45-
fflush(stdout);
46-
fflush(stderr);
41+
fflush(NULL);
4742

4843
#ifdef LINUX_PROFILE
4944

src/backend/postmaster/shell_archive.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ shell_archive_file(const char *file, const char *path)
9999
(errmsg_internal("executing archive command \"%s\"",
100100
xlogarchcmd)));
101101

102+
fflush(NULL);
102103
pgstat_report_wait_start(WAIT_EVENT_ARCHIVE_COMMAND);
103104
rc = system(xlogarchcmd);
104105
pgstat_report_wait_end();

src/backend/storage/file/fd.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2503,8 +2503,7 @@ OpenPipeStream(const char *command, const char *mode)
25032503
ReleaseLruFiles();
25042504

25052505
TryAgain:
2506-
fflush(stdout);
2507-
fflush(stderr);
2506+
fflush(NULL);
25082507
pqsignal(SIGPIPE, SIG_DFL);
25092508
errno = 0;
25102509
file = popen(command, mode);

src/backend/utils/error/elog.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -643,8 +643,7 @@ errfinish(const char *filename, int lineno, const char *funcname)
643643
* Any other code you might be tempted to add here should probably be
644644
* in an on_proc_exit or on_shmem_exit callback instead.
645645
*/
646-
fflush(stdout);
647-
fflush(stderr);
646+
fflush(NULL);
648647

649648
/*
650649
* Let the cumulative stats system know. Only mark the session as
@@ -670,8 +669,7 @@ errfinish(const char *filename, int lineno, const char *funcname)
670669
* XXX: what if we are *in* the postmaster? abort() won't kill our
671670
* children...
672671
*/
673-
fflush(stdout);
674-
fflush(stderr);
672+
fflush(NULL);
675673
abort();
676674
}
677675

src/bin/initdb/initdb.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -489,8 +489,7 @@ popen_check(const char *command, const char *mode)
489489
{
490490
FILE *cmdfd;
491491

492-
fflush(stdout);
493-
fflush(stderr);
492+
fflush(NULL);
494493
errno = 0;
495494
cmdfd = popen(command, mode);
496495
if (cmdfd == NULL)
@@ -914,6 +913,7 @@ test_config_settings(void)
914913
test_conns, test_buffs,
915914
dynamic_shared_memory_type,
916915
DEVNULL, DEVNULL);
916+
fflush(NULL);
917917
status = system(cmd);
918918
if (status == 0)
919919
{
@@ -950,6 +950,7 @@ test_config_settings(void)
950950
n_connections, test_buffs,
951951
dynamic_shared_memory_type,
952952
DEVNULL, DEVNULL);
953+
fflush(NULL);
953954
status = system(cmd);
954955
if (status == 0)
955956
break;

src/bin/pg_ctl/pg_ctl.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -448,8 +448,7 @@ start_postmaster(void)
448448
pgpid_t pm_pid;
449449

450450
/* Flush stdio channels just before fork, to avoid double-output problems */
451-
fflush(stdout);
452-
fflush(stderr);
451+
fflush(NULL);
453452

454453
#ifdef EXEC_BACKEND
455454
pg_disable_aslr();
@@ -916,6 +915,7 @@ do_init(void)
916915
cmd = psprintf("\"%s\" %s%s > \"%s\"",
917916
exec_path, pgdata_opt, post_opts, DEVNULL);
918917

918+
fflush(NULL);
919919
if (system(cmd) != 0)
920920
{
921921
write_stderr(_("%s: database system initialization failed\n"), progname);
@@ -2222,6 +2222,7 @@ adjust_data_dir(void)
22222222
my_exec_path,
22232223
pgdata_opt ? pgdata_opt : "",
22242224
post_opts ? post_opts : "");
2225+
fflush(NULL);
22252226

22262227
fd = popen(cmd, "r");
22272228
if (fd == NULL || fgets(filename, sizeof(filename), fd) == NULL)

src/bin/pg_dump/pg_dumpall.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1578,8 +1578,7 @@ runPgDump(const char *dbname, const char *create_opts)
15781578

15791579
pg_log_info("running \"%s\"", cmd->data);
15801580

1581-
fflush(stdout);
1582-
fflush(stderr);
1581+
fflush(NULL);
15831582

15841583
ret = system(cmd->data);
15851584

src/bin/pg_rewind/pg_rewind.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1151,6 +1151,7 @@ ensureCleanShutdown(const char *argv0)
11511151
appendPQExpBufferStr(postgres_cmd, " template1 < ");
11521152
appendShellString(postgres_cmd, DEVNULL);
11531153

1154+
fflush(NULL);
11541155
if (system(postgres_cmd->data) != 0)
11551156
{
11561157
pg_log_error("postgres single-user mode in target cluster failed");

src/bin/pg_upgrade/controldata.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,7 @@ get_control_data(ClusterInfo *cluster, bool live_check)
123123
/* only pg_controldata outputs the cluster state */
124124
snprintf(cmd, sizeof(cmd), "\"%s/pg_controldata\" \"%s\"",
125125
cluster->bindir, cluster->pgdata);
126-
fflush(stdout);
127-
fflush(stderr);
126+
fflush(NULL);
128127

129128
if ((output = popen(cmd, "r")) == NULL)
130129
pg_fatal("could not get control data using %s: %s",
@@ -191,8 +190,7 @@ get_control_data(ClusterInfo *cluster, bool live_check)
191190
cluster->bindir,
192191
live_check ? "pg_controldata\"" : resetwal_bin,
193192
cluster->pgdata);
194-
fflush(stdout);
195-
fflush(stderr);
193+
fflush(NULL);
196194

197195
if ((output = popen(cmd, "r")) == NULL)
198196
pg_fatal("could not get control data using %s: %s",

src/bin/pg_upgrade/exec.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ get_bin_version(ClusterInfo *cluster)
3939
v2 = 0;
4040

4141
snprintf(cmd, sizeof(cmd), "\"%s/pg_ctl\" --version", cluster->bindir);
42+
fflush(NULL);
4243

4344
if ((output = popen(cmd, "r")) == NULL ||
4445
fgets(cmd_output, sizeof(cmd_output), output) == NULL)
@@ -125,7 +126,10 @@ exec_prog(const char *log_filename, const char *opt_log_file,
125126
* the file do not see to help.
126127
*/
127128
if (mainThreadId != GetCurrentThreadId())
129+
{
130+
fflush(NULL);
128131
result = system(cmd);
132+
}
129133
#endif
130134

131135
log = fopen(log_file, "a");
@@ -174,7 +178,10 @@ exec_prog(const char *log_filename, const char *opt_log_file,
174178
/* see comment above */
175179
if (mainThreadId == GetCurrentThreadId())
176180
#endif
181+
{
182+
fflush(NULL);
177183
result = system(cmd);
184+
}
178185

179186
if (result != 0 && report_error)
180187
{

src/bin/pg_upgrade/option.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,7 @@ adjust_data_dir(ClusterInfo *cluster)
416416
*/
417417
snprintf(cmd, sizeof(cmd), "\"%s/postgres\" -D \"%s\" -C data_directory",
418418
cluster->bindir, cluster->pgconfig);
419+
fflush(NULL);
419420

420421
if ((output = popen(cmd, "r")) == NULL ||
421422
fgets(cmd_output, sizeof(cmd_output), output) == NULL)

src/bin/pg_verifybackup/pg_verifybackup.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -811,6 +811,7 @@ parse_required_wal(verifier_context *context, char *pg_waldump_path,
811811
pg_waldump_path, wal_directory, this_wal_range->tli,
812812
LSN_FORMAT_ARGS(this_wal_range->start_lsn),
813813
LSN_FORMAT_ARGS(this_wal_range->end_lsn));
814+
fflush(NULL);
814815
if (system(pg_waldump_cmd) != 0)
815816
report_backup_error(context,
816817
"WAL parsing failed for timeline %u",

src/bin/pgbench/pgbench.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2973,6 +2973,8 @@ runShellCommand(Variables *variables, char *variable, char **argv, int argc)
29732973

29742974
command[len] = '\0';
29752975

2976+
fflush(NULL); /* needed before either system() or popen() */
2977+
29762978
/* Fast path for non-assignment case */
29772979
if (variable == NULL)
29782980
{

src/bin/psql/command.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2661,6 +2661,7 @@ exec_command_write(PsqlScanState scan_state, bool active_branch,
26612661
if (fname[0] == '|')
26622662
{
26632663
is_pipe = true;
2664+
fflush(NULL);
26642665
disable_sigpipe_trap();
26652666
fd = popen(&fname[1], "w");
26662667
}
@@ -3834,6 +3835,7 @@ editFile(const char *fname, int lineno)
38343835
sys = psprintf("\"%s\" \"%s\"",
38353836
editorName, fname);
38363837
#endif
3838+
fflush(NULL);
38373839
result = system(sys);
38383840
if (result == -1)
38393841
pg_log_error("could not start editor \"%s\"", editorName);
@@ -4956,6 +4958,7 @@ do_shell(const char *command)
49564958
{
49574959
int result;
49584960

4961+
fflush(NULL);
49594962
if (!command)
49604963
{
49614964
char *sys;
@@ -5065,6 +5068,7 @@ do_watch(PQExpBuffer query_buf, double sleep)
50655068
#endif
50665069
if (pagerprog && myopt.topt.pager)
50675070
{
5071+
fflush(NULL);
50685072
disable_sigpipe_trap();
50695073
pagerpipe = popen(pagerprog, "w");
50705074

src/bin/psql/common.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ openQueryOutputFile(const char *fname, FILE **fout, bool *is_pipe)
5959
}
6060
else if (*fname == '|')
6161
{
62+
fflush(NULL);
6263
*fout = popen(fname + 1, "w");
6364
*is_pipe = true;
6465
}

src/bin/psql/copy.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -288,8 +288,7 @@ do_copy(const char *args)
288288
{
289289
if (options->program)
290290
{
291-
fflush(stdout);
292-
fflush(stderr);
291+
fflush(NULL);
293292
errno = 0;
294293
copystream = popen(options->file, PG_BINARY_R);
295294
}
@@ -307,10 +306,9 @@ do_copy(const char *args)
307306
{
308307
if (options->program)
309308
{
310-
fflush(stdout);
311-
fflush(stderr);
312-
errno = 0;
309+
fflush(NULL);
313310
disable_sigpipe_trap();
311+
errno = 0;
314312
copystream = popen(options->file, PG_BINARY_W);
315313
}
316314
else

src/bin/psql/prompt.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,8 +266,10 @@ get_prompt(promptStatus_t status, ConditionalStack cstack)
266266
{
267267
int cmdend = strcspn(p + 1, "`");
268268
char *file = pnstrdup(p + 1, cmdend);
269-
FILE *fd = popen(file, "r");
269+
FILE *fd;
270270

271+
fflush(NULL);
272+
fd = popen(file, "r");
271273
if (fd)
272274
{
273275
if (fgets(buf, sizeof(buf), fd) == NULL)

src/bin/psql/psqlscanslash.l

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -777,6 +777,7 @@ evaluate_backtick(PsqlScanState state)
777777

778778
initPQExpBuffer(&cmd_output);
779779

780+
fflush(NULL);
780781
fd = popen(cmd, "r");
781782
if (!fd)
782783
{

src/common/exec.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -388,9 +388,7 @@ pipe_read_line(char *cmd, char *line, int maxsize)
388388
{
389389
FILE *pgver;
390390

391-
/* flush output buffers in case popen does not... */
392-
fflush(stdout);
393-
fflush(stderr);
391+
fflush(NULL);
394392

395393
errno = 0;
396394
if ((pgver = popen(cmd, "r")) == NULL)

src/fe_utils/archive.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ RestoreArchivedFile(const char *path, const char *xlogfname,
5555
* Execute restore_command, which should copy the missing file from
5656
* archival storage.
5757
*/
58+
fflush(NULL);
5859
rc = system(xlogRestoreCmd);
5960
pfree(xlogRestoreCmd);
6061

src/fe_utils/print.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3118,6 +3118,7 @@ PageOutput(int lines, const printTableOpt *topt)
31183118
if (strspn(pagerprog, " \t\r\n") == strlen(pagerprog))
31193119
return stdout;
31203120
}
3121+
fflush(NULL);
31213122
disable_sigpipe_trap();
31223123
pagerpipe = popen(pagerprog, "w");
31233124
if (pagerpipe)

src/interfaces/libpq/fe-print.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ PQprint(FILE *fout, const PGresult *res, const PQprintOpt *po)
180180
- (po->header != 0) * 2 /* row count and newline */
181181
)))
182182
{
183+
fflush(NULL);
183184
fout = popen(pagerenv, "w");
184185
if (fout)
185186
{

0 commit comments

Comments
 (0)