On Windows, use COMSPEC to find the location of cmd.exe.
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 28 Oct 2019 18:15:03 +0000 (14:15 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 28 Oct 2019 18:15:03 +0000 (14:15 -0400)
Historically, psql consulted COMSPEC to spawn a shell in its \! command,
but we just invoked "cmd" when spawning shells in pg_ctl and pg_regress.
It seems better to rely on the environment variable, if it's set,
in all cases.

It's debatable whether this is a bug fix or just a behavioral change,
so no back-patch.

Juan José Santamaría Flecha

Discussion: https://postgr.es/m/16080-5d7f03222469f717@postgresql.org

src/bin/pg_ctl/pg_ctl.c
src/test/regress/pg_regress.c

index a3fd002ac47d8951555322871e869f31318fd638..95e5fafe1f41fdb451c4c21006492650f974e5d7 100644 (file)
@@ -513,13 +513,19 @@ start_postmaster(void)
     * "exec", so we don't get to find out the postmaster's PID immediately.
     */
    PROCESS_INFORMATION pi;
+   const char *comspec;
+
+   /* Find CMD.EXE location using COMSPEC, if it's set */
+   comspec = getenv("COMSPEC");
+   if (comspec == NULL)
+       comspec = "CMD";
 
    if (log_file != NULL)
-       snprintf(cmd, MAXPGPATH, "CMD /C \"\"%s\" %s%s < \"%s\" >> \"%s\" 2>&1\"",
-                exec_path, pgdata_opt, post_opts, DEVNULL, log_file);
+       snprintf(cmd, MAXPGPATH, "\"%s\" /C \"\"%s\" %s%s < \"%s\" >> \"%s\" 2>&1\"",
+                comspec, exec_path, pgdata_opt, post_opts, DEVNULL, log_file);
    else
-       snprintf(cmd, MAXPGPATH, "CMD /C \"\"%s\" %s%s < \"%s\" 2>&1\"",
-                exec_path, pgdata_opt, post_opts, DEVNULL);
+       snprintf(cmd, MAXPGPATH, "\"%s\" /C \"\"%s\" %s%s < \"%s\" 2>&1\"",
+                comspec, exec_path, pgdata_opt, post_opts, DEVNULL);
 
    if (!CreateRestrictedProcess(cmd, &pi, false))
    {
index 6554ce214bc02c3a5e08d51dc2f91667a45c58d6..297b8fbd6f95285e84285937ade9f4a47cbe2dd1 100644 (file)
@@ -1193,9 +1193,15 @@ spawn_process(const char *cmdline)
    PROCESS_INFORMATION pi;
    char       *cmdline2;
    HANDLE      restrictedToken;
+   const char *comspec;
+
+   /* Find CMD.EXE location using COMSPEC, if it's set */
+   comspec = getenv("COMSPEC");
+   if (comspec == NULL)
+       comspec = "CMD";
 
    memset(&pi, 0, sizeof(pi));
-   cmdline2 = psprintf("cmd /c \"%s\"", cmdline);
+   cmdline2 = psprintf("\"%s\" /c \"%s\"", comspec, cmdline);
 
    if ((restrictedToken =
         CreateRestrictedProcess(cmdline2, &pi)) == 0)