Re: pg_ctl start broken on windows - Mailing list pgsql-hackers-win32
From | Bruce Momjian |
---|---|
Subject | Re: pg_ctl start broken on windows |
Date | |
Msg-id | 200406101634.i5AGYcM28163@candle.pha.pa.us Whole thread Raw |
In response to | Re: pg_ctl start broken on windows (Andrew Dunstan <andrew@dunslane.net>) |
List | pgsql-hackers-win32 |
Andrew Dunstan wrote: > Bruce Momjian wrote: > > >Andrew Dunstan wrote: > > > > > >>>>C:\msys\1.0\local\pgsql>bin\pg_ctl -D data -l logfile start > >>>>'C:/msys/1.0/local/pgsql/bin/postmaster.exe" < nul >>"logfile' is not recognized as an internal or external command,operable program or batch file. > >>>> > >>>> > >>I'll test to make sure, but I can tell you now it won't work. It will > >>see the inner quotes and interpret them as part of the command. (I tried > >>all these variants when I was testing initdb). > >> > >> > > > >Claudio reported it worked for pg_dumpall for single quotes: > > > > system(''cmd.exe' 'arg1' 'arg2''); > > > >What exactly is the logic of the stripping? > > > >In fact, pg_ctl is wrong because it is using double quotes instead of > >the safer single quotes. Let me make that change. > > > > > > No. It chokes on forward slashes. > > and it tries to make a log file called 'logfile' (quotes included). > > I really don't see what the problem is with calling CreateProcess - it > should only be a few lines of code unless I'm much mistaken, and would > get us out of this setup that is really fragile at best. I did a lot of poking around in MinGW and found some basic rules. First, MinGW's system() can't use single quotes for the executable name or any file used in redirection (as you showed above). Second, it gets confused with multiple double-quoted strings. The fix is to add a double-quote to the beginning and end of the system string, so a typical system string becomes: system("\"\"ls\" 'a' 'b c' > \"out\"\"); Single quotes are fine for arguments. The applied patch makes this change and documents the behavior. Would folks test these changes on Win32 please? -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 359-1001 + If your life is a hard drive, | 13 Roberts Road + Christ can be your backup. | Newtown Square, Pennsylvania 19073 Index: src/bin/initdb/initdb.c =================================================================== RCS file: /cvsroot/pgsql-server/src/bin/initdb/initdb.c,v retrieving revision 1.35 diff -c -c -r1.35 initdb.c *** src/bin/initdb/initdb.c 3 Jun 2004 00:07:36 -0000 1.35 --- src/bin/initdb/initdb.c 10 Jun 2004 16:24:17 -0000 *************** *** 812,823 **** for (i = 0; i < len; i++) { snprintf(cmd, sizeof(cmd), ! "\"%s\" -boot -x0 %s " "-c shared_buffers=%d -c max_connections=%d template1 " ! "<%s >%s 2>&1", ! backend_exec, boot_options, conns[i] * 5, conns[i], ! DEVNULL, DEVNULL); status = system(cmd); if (status == 0) break; --- 812,823 ---- for (i = 0; i < len; i++) { snprintf(cmd, sizeof(cmd), ! "%s\"%s\" -boot -x0 %s " "-c shared_buffers=%d -c max_connections=%d template1 " ! "< \"%s\" > \"%s\" 2>&1%s", ! SYSTEMQUOTE, backend_exec, boot_options, conns[i] * 5, conns[i], ! DEVNULL, DEVNULL, SYSTEMQUOTE); status = system(cmd); if (status == 0) break; *************** *** 848,859 **** for (i = 0; i < len; i++) { snprintf(cmd, sizeof(cmd), ! "\"%s\" -boot -x0 %s " "-c shared_buffers=%d -c max_connections=%d template1 " ! "<%s >%s 2>&1", ! backend_exec, boot_options, bufs[i], n_connections, ! DEVNULL, DEVNULL); status = system(cmd); if (status == 0) break; --- 848,859 ---- for (i = 0; i < len; i++) { snprintf(cmd, sizeof(cmd), ! "%s\"%s\" -boot -x0 %s " "-c shared_buffers=%d -c max_connections=%d template1 " ! "< \"%s\" > \"%s\" 2>&1%s", ! SYSTEMQUOTE, backend_exec, boot_options, bufs[i], n_connections, ! DEVNULL, DEVNULL, SYSTEMQUOTE); status = system(cmd); if (status == 0) break; Index: src/bin/pg_ctl/pg_ctl.c =================================================================== RCS file: /cvsroot/pgsql-server/src/bin/pg_ctl/pg_ctl.c,v retrieving revision 1.8 diff -c -c -r1.8 pg_ctl.c *** src/bin/pg_ctl/pg_ctl.c 9 Jun 2004 17:36:07 -0000 1.8 --- src/bin/pg_ctl/pg_ctl.c 10 Jun 2004 16:24:17 -0000 *************** *** 224,234 **** /* Does '&' work on Win32? */ if (log_file != NULL) ! snprintf(cmd, MAXPGPATH, "'%s' %s < %s >> '%s' 2>&1 &", ! postgres_path, post_opts, DEVNULL, log_file); else ! snprintf(cmd, MAXPGPATH, "'%s' %s < %s 2>&1 &", ! postgres_path, post_opts, DEVNULL); return system(cmd); } --- 224,235 ---- /* Does '&' work on Win32? */ if (log_file != NULL) ! snprintf(cmd, MAXPGPATH, "%s\"%s\" %s < %s >> \"%s\" 2>&1 &%s", ! SYSTEMQUOTE, postgres_path, post_opts, DEVNULL, log_file, ! SYSTEMQUOTE); else ! snprintf(cmd, MAXPGPATH, "%s\"%s\" %s < \"%s\" 2>&1 &%s", ! SYSTEMQUOTE, postgres_path, post_opts, DEVNULL, SYSTEMQUOTE); return system(cmd); } Index: src/bin/pg_dump/pg_dumpall.c =================================================================== RCS file: /cvsroot/pgsql-server/src/bin/pg_dump/pg_dumpall.c,v retrieving revision 1.40 diff -c -c -r1.40 pg_dumpall.c *** src/bin/pg_dump/pg_dumpall.c 9 Jun 2004 17:37:28 -0000 1.40 --- src/bin/pg_dump/pg_dumpall.c 10 Jun 2004 16:24:18 -0000 *************** *** 690,696 **** const char *p; int ret; ! appendPQExpBuffer(cmd, "'%s' %s -Fp '", pg_dump_bin, pgdumpopts->data); /* Shell quoting is not quite like SQL quoting, so can't use fmtId */ for (p = dbname; *p; p++) --- 690,697 ---- const char *p; int ret; ! appendPQExpBuffer(cmd, "%s\"%s\" %s -Fp '", SYSTEMQUOTE, pg_dump_bin, ! pgdumpopts->data); /* Shell quoting is not quite like SQL quoting, so can't use fmtId */ for (p = dbname; *p; p++) *************** *** 702,707 **** --- 703,709 ---- } appendPQExpBufferChar(cmd, '\''); + appendStringLiteral(cmd, SYSTEMQUOTE, false); if (verbose) fprintf(stderr, _("%s: running \"%s\"\n"), progname, cmd->data); Index: src/include/port.h =================================================================== RCS file: /cvsroot/pgsql-server/src/include/port.h,v retrieving revision 1.40 diff -c -c -r1.40 port.h *** src/include/port.h 3 Jun 2004 00:07:38 -0000 1.40 --- src/include/port.h 10 Jun 2004 16:24:18 -0000 *************** *** 72,77 **** --- 72,89 ---- #define DEVNULL "/dev/null" #endif + /* + * Win32 needs double quotes at the beginning and end of system() + * strings. If not, it gets confused with multiple quoted strings. + * It also must use double-quotes around the executable name + * and any files use for redirection. Other args can use single-quotes. + */ + #ifdef WIN32 + #define SYSTEMQUOTE "\"" + #else + #define SYSTEMQUOTE "" + #endif + /* Portable delay handling */ extern void pg_usleep(long microsec);
pgsql-hackers-win32 by date: