diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c index 6a36d29..07345d8 100644 --- a/src/bin/pg_ctl/pg_ctl.c +++ b/src/bin/pg_ctl/pg_ctl.c @@ -73,6 +73,15 @@ typedef enum RUN_AS_SERVICE_COMMAND } CtlCommand; +#if defined(WIN32) || defined(__CYGWIN__) +typedef enum +{ + WinLogOutput_default, + WinLogOutput_stderr, + WinLogOutput_eventlog +} WinLogOutput; +#endif + #define DEFAULT_WAIT 60 static bool do_wait = false; @@ -110,6 +119,7 @@ static SERVICE_STATUS status; static SERVICE_STATUS_HANDLE hStatus = (SERVICE_STATUS_HANDLE) 0; static HANDLE shutdownHandles[2]; static pid_t postmasterPID = -1; +static WinLogOutput log_output = WinLogOutput_default; #define shutdownEvent shutdownHandles[0] #define postmasterProcess shutdownHandles[1] @@ -212,10 +222,11 @@ write_stderr(const char *fmt,...) #else /* - * On Win32, we print to stderr if running on a console, or write to - * eventlog if running as a service + * On Win32, we write to eventlog if eventlog is enforced or running as a service, + * otherwise write to stderr */ - if (!isatty(fileno(stderr))) /* Running as a service */ + if (log_output == WinLogOutput_eventlog /* eventlog is enforced */ + || (log_output == WinLogOutput_default && !isatty(fileno(stderr)))) /* or running as a service */ { char errbuf[2048]; /* Arbitrary size? */ @@ -224,7 +235,7 @@ write_stderr(const char *fmt,...) write_eventlog(EVENTLOG_ERROR_TYPE, errbuf); } else - /* Not running as service, write to stderr */ + /* stderr is enforced or not running as a service, write to stderr */ vfprintf(stderr, fmt, ap); #endif va_end(ap); @@ -1927,6 +1938,16 @@ do_help(void) printf(_("(The default is to wait for shutdown, but not for start or restart.)\n\n")); printf(_("If the -D option is omitted, the environment variable PGDATA is used.\n")); +#if defined(WIN32) || defined(__CYGWIN__) + printf(_("\nCommon options for logging errors:\n")); + printf(_(" --log-output=OUT OUT can be \"default\", \"stderr\", or \"eventlog\"\n")); + printf(_("\nLog outputs are:\n")); + printf(_(" default log errors to Windows Event Log if running as a service,\n" + " otherwise log to stderr\n")); + printf(_(" stderr log errors to stderr\n")); + printf(_(" eventlog log errors to Windows Event Log\n")); +#endif + printf(_("\nOptions for start or restart:\n")); #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE) printf(_(" -c, --core-files allow postgres to produce core files\n")); @@ -2104,6 +2125,12 @@ adjust_data_dir(void) canonicalize_path(pg_data); } +typedef enum +{ +#if defined(WIN32) || defined(__CYGWIN__) + OptionLogOutput = 1000 +#endif +} LongOnlyOption; int main(int argc, char **argv) @@ -2117,6 +2144,9 @@ main(int argc, char **argv) {"silent", no_argument, NULL, 's'}, {"timeout", required_argument, NULL, 't'}, {"core-files", no_argument, NULL, 'c'}, +#if defined(WIN32) || defined(__CYGWIN__) + {"log-output", required_argument, NULL, OptionLogOutput}, +#endif {NULL, 0, NULL, 0} }; @@ -2266,6 +2296,20 @@ main(int argc, char **argv) case 'c': allow_core_files = true; break; +#if defined(WIN32) || defined(__CYGWIN__) + case OptionLogOutput: + if (strcmp(optarg, "default") == 0) + log_output = WinLogOutput_default; + else if (strcmp(optarg, "stderr") == 0) + log_output = WinLogOutput_stderr; + else if (strcmp(optarg, "eventlog") == 0) + log_output = WinLogOutput_eventlog; + else { + do_advice(); + exit(1); + } + break; +#endif default: /* getopt_long already issued a suitable error message */ do_advice();