aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bin/pg_ctl/pg_ctl.c28
1 files changed, 21 insertions, 7 deletions
diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c
index 6ee88226691..3668f35b222 100644
--- a/src/bin/pg_ctl/pg_ctl.c
+++ b/src/bin/pg_ctl/pg_ctl.c
@@ -521,23 +521,37 @@ start_postmaster(void)
if (log_file != NULL)
{
/*
- * First, touch the log file. The main value of this is that if the
+ * First, open the log file if it exists. The idea is that if the
* file is still locked by a previous postmaster run, we'll wait until
* it comes free, instead of failing with ERROR_SHARING_VIOLATION.
* (It'd be better to open the file in a sharing-friendly mode, but we
* can't use CMD.EXE to do that, so work around it. Note that the
* previous postmaster will still have the file open for a short time
* after removing postmaster.pid.)
+ *
+ * If the log file doesn't exist, we *must not* create it here. If we
+ * were launched with higher privileges than the restricted process
+ * will have, the log file might end up with permissions settings that
+ * prevent the postmaster from writing on it.
*/
- FILE *fd = fopen(log_file, "a");
+ int fd = open(log_file, O_RDWR, 0);
- if (fd == NULL)
+ if (fd == -1)
{
- write_stderr(_("%s: could not create log file \"%s\": %s\n"),
- progname, log_file, strerror(errno));
- exit(1);
+ /*
+ * ENOENT is expectable since we didn't use O_CREAT. Otherwise
+ * complain. We could just fall through and let CMD.EXE report
+ * the problem, but its error reporting is pretty miserable.
+ */
+ if (errno != ENOENT)
+ {
+ write_stderr(_("%s: could not open log file \"%s\": %s\n"),
+ progname, log_file, strerror(errno));
+ exit(1);
+ }
}
- fclose(fd);
+ else
+ close(fd);
snprintf(cmd, MAXPGPATH, "\"%s\" /C \"\"%s\" %s%s < \"%s\" >> \"%s\" 2>&1\"",
comspec, exec_path, pgdata_opt, post_opts, DEVNULL, log_file);