diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c index 32fce00d760e41e3c952bac4a598f5faa772550e..6379a2a9ab5dc9ea11f8bff6851cb5f25906c6f1 100644 --- a/src/bin/pg_ctl/pg_ctl.c +++ b/src/bin/pg_ctl/pg_ctl.c @@ -18,7 +18,9 @@ #endif #include "postgres_fe.h" + #include "libpq-fe.h" +#include "pqexpbuffer.h" #include <fcntl.h> #include <locale.h> @@ -1265,16 +1267,13 @@ pgwin32_IsInstalled(SC_HANDLE hSCM) static char * pgwin32_CommandLine(bool registration) { - static char cmdLine[MAXPGPATH]; + PQExpBuffer cmdLine = createPQExpBuffer(); + char cmdPath[MAXPGPATH]; int ret; -#ifdef __CYGWIN__ - char buf[MAXPGPATH]; -#endif - if (registration) { - ret = find_my_exec(argv0, cmdLine); + ret = find_my_exec(argv0, cmdPath); if (ret != 0) { write_stderr(_("%s: could not find own program executable\n"), progname); @@ -1284,7 +1283,7 @@ pgwin32_CommandLine(bool registration) else { ret = find_other_exec(argv0, "postgres", PG_BACKEND_VERSIONSTR, - cmdLine); + cmdPath); if (ret != 0) { write_stderr(_("%s: could not find postgres program executable\n"), progname); @@ -1294,54 +1293,57 @@ pgwin32_CommandLine(bool registration) #ifdef __CYGWIN__ /* need to convert to windows path */ + { + char buf[MAXPGPATH]; + #if CYGWIN_VERSION_DLL_MAJOR >= 1007 - cygwin_conv_path(CCP_POSIX_TO_WIN_A, cmdLine, buf, sizeof(buf)); + cygwin_conv_path(CCP_POSIX_TO_WIN_A, cmdPath, buf, sizeof(buf)); #else - cygwin_conv_to_full_win32_path(cmdLine, buf); + cygwin_conv_to_full_win32_path(cmdPath, buf); #endif - strcpy(cmdLine, buf); + strcpy(cmdPath, buf); + } #endif + /* if path does not end in .exe, append it */ + if (strlen(cmdPath) < 4 || + pg_strcasecmp(cmdPath + strlen(cmdPath) - 4, ".exe") != 0) + snprintf(cmdPath + strlen(cmdPath), sizeof(cmdPath) - strlen(cmdPath), + ".exe"); + + /* use backslashes in path to avoid problems with some third-party tools */ + make_native_path(cmdPath); + + /* be sure to double-quote the executable's name in the command */ + appendPQExpBuffer(cmdLine, "\"%s\"", cmdPath); + + /* append assorted switches to the command line, as needed */ + if (registration) - { - if (pg_strcasecmp(cmdLine + strlen(cmdLine) - 4, ".exe") != 0) - { - /* If commandline does not end in .exe, append it */ - strcat(cmdLine, ".exe"); - } - strcat(cmdLine, " runservice -N \""); - strcat(cmdLine, register_servicename); - strcat(cmdLine, "\""); - } + appendPQExpBuffer(cmdLine, " runservice -N \"%s\"", + register_servicename); if (pg_config) - { - strcat(cmdLine, " -D \""); - strcat(cmdLine, pg_config); - strcat(cmdLine, "\""); - } + appendPQExpBuffer(cmdLine, " -D \"%s\"", pg_config); if (registration && do_wait) - strcat(cmdLine, " -w"); + appendPQExpBuffer(cmdLine, " -w"); if (registration && wait_seconds != DEFAULT_WAIT) - /* concatenate */ - sprintf(cmdLine + strlen(cmdLine), " -t %d", wait_seconds); + appendPQExpBuffer(cmdLine, " -t %d", wait_seconds); if (registration && silent_mode) - strcat(cmdLine, " -s"); + appendPQExpBuffer(cmdLine, " -s"); if (post_opts) { - strcat(cmdLine, " "); - if (registration) - strcat(cmdLine, " -o \""); - strcat(cmdLine, post_opts); if (registration) - strcat(cmdLine, "\""); + appendPQExpBuffer(cmdLine, " -o \"%s\"", post_opts); + else + appendPQExpBuffer(cmdLine, " %s", post_opts); } - return cmdLine; + return cmdLine->data; } static void @@ -1772,7 +1774,7 @@ CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo, bool as_ser */ return r; } -#endif +#endif /* defined(WIN32) || defined(__CYGWIN__) */ static void do_advice(void)