Index: postmaster.c =================================================================== RCS file: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v retrieving revision 1.589 diff -c -r1.589 postmaster.c *** postmaster.c 24 Aug 2009 18:09:37 -0000 1.589 --- postmaster.c 24 Aug 2009 19:22:28 -0000 *************** *** 191,197 **** /* still more option variables */ bool EnableSSL = false; ! bool SilentMode = false; /* silent mode (-S) */ int PreAuthDelay = 0; int AuthenticationTimeout = 60; --- 191,197 ---- /* still more option variables */ bool EnableSSL = false; ! bool SilentMode = false; /* silent_mode */ int PreAuthDelay = 0; int AuthenticationTimeout = 60; *************** *** 744,750 **** } /* ! * Fork away from controlling terminal, if -S specified. * * Must do this before we grab any interlock files, else the interlocks * will show the wrong PID. --- 744,750 ---- } /* ! * Fork away from controlling terminal, if silent_mode specified. * * Must do this before we grab any interlock files, else the interlocks * will show the wrong PID. *************** *** 1204,1218 **** /* ! * Fork away from the controlling terminal (-S option) */ static void pmdaemonize(void) { #ifndef WIN32 ! int i; pid_t pid; pid = fork_process(); if (pid == (pid_t) -1) { --- 1204,1249 ---- /* ! * Fork away from the controlling terminal (silent_mode option) ! * ! * Since this requires disconnecting from stdin/stdout/stderr (in case they're ! * linked to the terminal), we re-point stdin to /dev/null and stdout/stderr ! * to "postmaster.log" in the data directory, where we're already chdir'd. */ static void pmdaemonize(void) { #ifndef WIN32 ! const char *pmlogname = "postmaster.log"; ! int dvnull; ! int pmlog; pid_t pid; + int res; + /* + * Make sure we can open the files we're going to redirect to. If this + * fails, we want to complain before disconnecting. Mention the full path + * of the logfile in the error message, even though we address it by + * relative path. + */ + dvnull = open(DEVNULL, O_RDONLY, 0); + if (dvnull < 0) + { + write_stderr("%s: could not open file \"%s\": %s\n", + progname, DEVNULL, strerror(errno)); + ExitPostmaster(1); + } + pmlog = open(pmlogname, O_CREAT | O_WRONLY | O_APPEND, 0600); + if (pmlog < 0) + { + write_stderr("%s: could not open log file \"%s/%s\": %s\n", + progname, DataDir, pmlogname, strerror(errno)); + ExitPostmaster(1); + } + + /* + * Okay to fork. + */ pid = fork_process(); if (pid == (pid_t) -1) { *************** *** 1231,1238 **** MyStartTime = time(NULL); /* ! * GH: If there's no setsid(), we hopefully don't need silent mode. Until ! * there's a better solution. */ #ifdef HAVE_SETSID if (setsid() < 0) --- 1262,1269 ---- MyStartTime = time(NULL); /* ! * Some systems use setsid() to dissociate from the TTY's process group, ! * while on others it depends on stdin/stdout/stderr. Do both if possible. */ #ifdef HAVE_SETSID if (setsid() < 0) *************** *** 1242,1255 **** ExitPostmaster(1); } #endif ! i = open(DEVNULL, O_RDWR, 0); ! dup2(i, 0); ! dup2(i, 1); ! dup2(i, 2); ! close(i); #else /* WIN32 */ /* not supported */ ! elog(FATAL, "SilentMode not supported under WIN32"); #endif /* WIN32 */ } --- 1273,1298 ---- ExitPostmaster(1); } #endif ! ! /* ! * Reassociate stdin/stdout/stderr. fork_process() cleared any pending ! * output, so this should be safe. The only plausible error is EINTR, ! * which just means we should retry. ! */ ! do { ! res = dup2(dvnull, 0); ! } while (res < 0 && errno == EINTR); ! close(dvnull); ! do { ! res = dup2(pmlog, 1); ! } while (res < 0 && errno == EINTR); ! do { ! res = dup2(pmlog, 2); ! } while (res < 0 && errno == EINTR); ! close(pmlog); #else /* WIN32 */ /* not supported */ ! elog(FATAL, "silent_mode is not supported under Windows"); #endif /* WIN32 */ }