Re: [HACKERS] Fix initdb for path with whitespace and at char

2014-05-05 Thread Heikki Linnakangas

On 05/01/2014 07:55 AM, Amit Kapila wrote:

On Wed, Apr 30, 2014 at 4:01 PM, Heikki Linnakangas
hlinnakan...@vmware.com wrote:

I committed the non-invasive fixes to backbranches (and master too, just to
keep it in sync), but the attached is what I came up with for master.

There are a couple of places in the code where we have #ifdef WIN32 code
that uses CreateProcess with CMD /C ... directly.


1. Do we need similar handling for CreatePipe case where it directly uses
executable path such as in function pipe_read_line()?
Currently the caller of pipe_read_line() calls canonicalize_path() to change
win32 specific path, is that sufficient or do we need SYSTEMQUOTE type
of handling for it.


No, SYSTEMQUOTE style handling is not required with CreateProcess. 
find_other_exec, which is the only caller of pipe_read_line, adds one 
pair of double-quotes around the executable's path, which is enough for 
CreateProcess.



2.
system.c
#include assert.h
Do we really need inclusion of assert.h or this is for future use?


You're right, that's not needed.


3. One more observation is that currently install.bat doesn't work
for such paths:
install.bat e:\PostgreSQL\master\install 1\ins@1
1\ins@1== was unexpected at this time.


Yeah, I noticed that. I haven't looked into what it would take to fix 
that, but for now you can just install to a path that doesn't contain 
whitespace, and move it from there. install.bat is only used by 
developers / packagers, so that's not a big deal.



4. Similar to Andrew, I also could not reproduce this problem on my
Windows system (Windows 7 64 bit)
e:\e:\PostgreSQL\master\install 1\ins@1\bin\initdb.exe -D e:
\PostgreSQL\master\Data 1
e:\e:\PostgreSQL\master\install 1\ins@1\bin\pg_ctl.exe start -D e:
\PostgreSQL\master\Data 1

Above commands work fine.


Hmm, I'm also testing on 64-bit Windows 7, and it failed for me. Note 
that I already committed the narrow fix for initdb - which I also 
backpatched - to master, so to reproduce you'll need to revert that 
locally (commit 503de546).


I fixed the issues with malloc that Tom pointed out and committed the 
wrapper functions to git master. But please let me know if there's still 
a problem with it.


- Heikki


--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] Fix initdb for path with whitespace and at char

2014-05-05 Thread Amit Kapila
On Mon, May 5, 2014 at 6:38 PM, Heikki Linnakangas
hlinnakan...@vmware.com wrote:
 On 05/01/2014 07:55 AM, Amit Kapila wrote:
 4. Similar to Andrew, I also could not reproduce this problem on my
 Windows system (Windows 7 64 bit)
 e:\e:\PostgreSQL\master\install 1\ins@1\bin\initdb.exe -D e:
 \PostgreSQL\master\Data 1
 e:\e:\PostgreSQL\master\install 1\ins@1\bin\pg_ctl.exe start -D e:
 \PostgreSQL\master\Data 1

 Above commands work fine.


 Hmm, I'm also testing on 64-bit Windows 7, and it failed for me. Note that I
 already committed the narrow fix for initdb - which I also backpatched - to
 master, so to reproduce you'll need to revert that locally (commit
 503de546).

After reverting the specified commit, I could reproduce the issue and
verified HEAD(it is fixed).

With Regards,
Amit Kapila.
EnterpriseDB: http://www.enterprisedb.com


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] Fix initdb for path with whitespace and at char

2014-04-30 Thread Heikki Linnakangas

On 04/30/2014 07:39 AM, Amit Kapila wrote:

On Wed, Apr 30, 2014 at 3:57 AM, Tom Lane t...@sss.pgh.pa.us wrote:

Heikki Linnakangas hlinnakan...@vmware.com writes:

This looks correct to me. popen() requires SYSTEMQUOTEs on Windows, like
system() does.


It seems right now  SYSTEMQUOTE is used before popen both for
Windows and non-Windows, ex. adjust_data_dir() in pg_ctl.c


Yeah, but it's defined to an empty string on non-Windows platforms.


We might forget to use the wrapper function too, if it has a nonstandard
name, no?  A better idea would be to redefine popen() and system() on
Windows.  It looks like we're already using a #define to redefine popen().


Right, that's exactly what I meant by a wrapper function.


Won't defining variant of popen just for Windows to add SYSTEMQUOTE
effect such (where currently it is used for both win and non-winows)
usage?  Also, I think we might want to remove use of SYSTEMQUOTE
before popen calls where ever it is currently used to avoid usage of the
same two times.


Yep.

I'll write up a patch to do that for git master. For back-branches, I 
just added the missing SYSTEMQUOTEs. There are a couple of places where 
changing the behavior might break existing installations. In particular, 
in the stable branches it's probably best to not add the SYSTEMQUOTEs to 
things like archive_command, restore_command, and COPY TO/FROM PROGRAM, 
where the command is specified by the user. Because people might already 
have added the extra quotes to the command to make it work, and if we 
suddenly start adding yet another pair of quotes, it will stop working.


- Heikki


--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] Fix initdb for path with whitespace and at char

2014-04-30 Thread Heikki Linnakangas
I committed the non-invasive fixes to backbranches (and master too, just 
to keep it in sync), but the attached is what I came up with for master.


There are a couple of places in the code where we have #ifdef WIN32 code 
that uses CreateProcess with CMD /C ... directly. I believe those are 
currently (ie. before this patch) wrong for cygwin builds. SYSTEMQUOTE 
is defined as:


#if defined(WIN32)  !defined(__CYGWIN__)
#define SYSTEMQUOTE \
#else
#define SYSTEMQUOTE 
#endif

I presume the !CYGWIN part is because cygwin version of system() and 
popen() don't require the extra quoting, because cygwin does that for 
us. But when we use CreateProcess directly, e.g like this in pg_ctl.c:


  snprintf(cmd, MAXPGPATH, CMD /C  SYSTEMQUOTE \\%s\ %s%s  
\%s\ 21\ SYSTEMQUOTE,

   exec_path, pgdata_opt, post_opts, DEVNULL);

  if (!CreateRestrictedProcess(cmd, pi, false))
return GetLastError();

we would need the extra quotes, but SYSTEMQUOTE doesn't provide them 
with cygwin.



Andrew: you have a cygwin installation, don't you? Could you test if 
pg_ctl start works when the binaries are installed to a path that 
contains both a space and an @ sign, like C:\white 
space\at@sign\install. I suspect it doesn't, but the attached patch 
fixes it.


- Heikki
From b00134385de28361194e7ba0a050343bb581e058 Mon Sep 17 00:00:00 2001
From: Heikki Linnakangas heikki.linnakan...@iki.fi
Date: Wed, 30 Apr 2014 10:23:14 +0300
Subject: [PATCH] Replace SYSTEMQUOTEs with Windows-specific wrapper functions.

It's easy to forget using SYSTEMQUOTEs whe constructing command strings
for system() or popen(). We are currently missing it e.g. in COPY TO/FROM
PROGRAM calls. Even if we fix all the places missing it now, it is bound
to be forgotten again in the future. To eliminate the need for that, add
wrapper functions that do the the extra quoting for you, and get rid of
SYSTEMQUOTEs in all the callers.

diff --git a/configure.in b/configure.in
index fc9c52f..52357a6 100644
--- a/configure.in
+++ b/configure.in
@@ -1353,6 +1353,7 @@ if test $PORTNAME = win32; then
   AC_REPLACE_FUNCS(gettimeofday)
   AC_LIBOBJ(kill)
   AC_LIBOBJ(open)
+  AC_LIBOBJ(system)
   AC_LIBOBJ(win32env)
   AC_LIBOBJ(win32error)
   AC_LIBOBJ(win32setlocale)
diff --git a/contrib/pg_upgrade/check.c b/contrib/pg_upgrade/check.c
index 56e912d..d22b6d3 100644
--- a/contrib/pg_upgrade/check.c
+++ b/contrib/pg_upgrade/check.c
@@ -970,7 +970,7 @@ get_bin_version(ClusterInfo *cluster)
 	int			pre_dot,
 post_dot;
 
-	snprintf(cmd, sizeof(cmd), SYSTEMQUOTE \%s/pg_ctl\ --version SYSTEMQUOTE, cluster-bindir);
+	snprintf(cmd, sizeof(cmd), \%s/pg_ctl\ --version, cluster-bindir);
 
 	if ((output = popen(cmd, r)) == NULL ||
 		fgets(cmd_output, sizeof(cmd_output), output) == NULL)
diff --git a/contrib/pg_upgrade/controldata.c b/contrib/pg_upgrade/controldata.c
index fa0a005..476c6be 100644
--- a/contrib/pg_upgrade/controldata.c
+++ b/contrib/pg_upgrade/controldata.c
@@ -110,7 +110,7 @@ get_control_data(ClusterInfo *cluster, bool live_check)
 	pg_putenv(LC_ALL, NULL);
 	pg_putenv(LC_MESSAGES, C);
 
-	snprintf(cmd, sizeof(cmd), SYSTEMQUOTE \%s/%s \%s\ SYSTEMQUOTE,
+	snprintf(cmd, sizeof(cmd), \%s/%s \%s\,
 			 cluster-bindir,
 			 live_check ? pg_controldata\ : pg_resetxlog\ -n,
 			 cluster-pgdata);
diff --git a/contrib/pg_upgrade/exec.c b/contrib/pg_upgrade/exec.c
index 7f01301..91e66e6 100644
--- a/contrib/pg_upgrade/exec.c
+++ b/contrib/pg_upgrade/exec.c
@@ -59,14 +59,14 @@ static DWORD   mainThreadId = 0;
 		mainThreadId = GetCurrentThreadId();
 #endif
 
-	written = strlcpy(cmd, SYSTEMQUOTE, sizeof(cmd));
+	written = 0;
 	va_start(ap, fmt);
 	written += vsnprintf(cmd + written, MAXCMDLEN - written, fmt, ap);
 	va_end(ap);
 	if (written = MAXCMDLEN)
 		pg_fatal(command too long\n);
 	written += snprintf(cmd + written, MAXCMDLEN - written,
-		  \%s\ 21 SYSTEMQUOTE, log_file);
+		  \%s\ 21, log_file);
 	if (written = MAXCMDLEN)
 		pg_fatal(command too long\n);
 
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index b53fa8b..83b7f6e 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -1130,11 +1130,11 @@ test_config_settings(void)
 		test_buffs = MIN_BUFS_FOR_CONNS(test_conns);
 
 		snprintf(cmd, sizeof(cmd),
- SYSTEMQUOTE \%s\ --boot -x0 %s 
+ \%s\ --boot -x0 %s 
  -c max_connections=%d 
  -c shared_buffers=%d 
  -c dynamic_shared_memory_type=none 
-  \%s\  \%s\ 21 SYSTEMQUOTE,
+  \%s\  \%s\ 21,
  backend_exec, boot_options,
  test_conns, test_buffs,
  DEVNULL, DEVNULL);
@@ -1165,11 +1165,11 @@ test_config_settings(void)
 		}
 
 		snprintf(cmd, sizeof(cmd),
- SYSTEMQUOTE \%s\ --boot -x0 %s 
+ \%s\ --boot -x0 %s 
  -c max_connections=%d 
  -c shared_buffers=%d 
  -c dynamic_shared_memory_type=none 
-  \%s\  \%s\ 21 SYSTEMQUOTE,
+  \%s\  \%s\ 21,
  backend_exec, boot_options,
  n_connections, test_buffs,
  DEVNULL, DEVNULL);
@@ -1503,7 +1503,7 @@ 

Re: [HACKERS] Fix initdb for path with whitespace and at char

2014-04-30 Thread Andrew Dunstan


On 04/30/2014 06:31 AM, Heikki Linnakangas wrote:




Andrew: you have a cygwin installation, don't you? Could you test if 
pg_ctl start works when the binaries are installed to a path that 
contains both a space and an @ sign, like C:\white 
space\at@sign\install. I suspect it doesn't, but the attached patch 
fixes it.






I'll see what I can do.

cheers

andrew



--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] Fix initdb for path with whitespace and at char

2014-04-30 Thread Tom Lane
Heikki Linnakangas hlinnakan...@vmware.com writes:
 I committed the non-invasive fixes to backbranches (and master too, just 
 to keep it in sync), but the attached is what I came up with for master.

The malloc's in the new system.c file should be pg_malloc, or else have
custom defenses against out-of-memory (possibly returning ENOMEM to
the caller would be best?).  Also, it seems like a good idea to save and
restore errno across the ending free() calls.  I don't know if Windows'
version of free() can change errno, but we've definitely found that to
be possible on other platforms.

Looks good otherwise.

regards, tom lane


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] Fix initdb for path with whitespace and at char

2014-04-30 Thread Andrew Dunstan


On 04/30/2014 11:58 AM, Andrew Dunstan wrote:


On 04/30/2014 06:31 AM, Heikki Linnakangas wrote:




Andrew: you have a cygwin installation, don't you? Could you test if 
pg_ctl start works when the binaries are installed to a path that 
contains both a space and an @ sign, like C:\white 
space\at@sign\install. I suspect it doesn't, but the attached patch 
fixes it.






I'll see what I can do.




I tried git master like this:

   foo\ bar/a\@b/bin/initdb.exe data
   foo\ bar/a\@b/bin/pg_ctl.exe -D data/ -w start

and didn't encounter a problem.

Platform is Windows 8 Pro 64 bit, with latest 32 bit Cygwin.


[ ... ] It looks like possibly the only time this will actually matter 
on Cygwin  is when starting a service. Just running pg_ctl start from 
the command line works fine. But starting the service doesn't.


I'll try the patch when I get a chance.

cheers

andrew









cheers

andrew







--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] Fix initdb for path with whitespace and at char

2014-04-30 Thread Andrew Dunstan


On 04/30/2014 03:03 PM, Andrew Dunstan wrote:


On 04/30/2014 11:58 AM, Andrew Dunstan wrote:


On 04/30/2014 06:31 AM, Heikki Linnakangas wrote:




Andrew: you have a cygwin installation, don't you? Could you test if
pg_ctl start works when the binaries are installed to a path that
contains both a space and an @ sign, like C:\white
space\at@sign\install. I suspect it doesn't, but the attached patch
fixes it.





I'll see what I can do.




I tried git master like this:

   foo\ bar/a\@b/bin/initdb.exe data
   foo\ bar/a\@b/bin/pg_ctl.exe -D data/ -w start

and didn't encounter a problem.

Platform is Windows 8 Pro 64 bit, with latest 32 bit Cygwin.


[ ... ] It looks like possibly the only time this will actually matter
on Cygwin  is when starting a service. Just running pg_ctl start
from the command line works fine. But starting the service doesn't.

I'll try the patch when I get a chance.






No, there is something horribly wrong with the Cygwin service code. I 
don't have time now to sort it out.  I suspect it's been broken for a 
very long time. I'm not even sure why we have it. Cygwin contains a 
wrapper (cygrunsrv) for setting up cygwin executables as services, so 
this is probably worse than redundant.


cheers

andrew





--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] Fix initdb for path with whitespace and at char

2014-04-30 Thread Amit Kapila
On Wed, Apr 30, 2014 at 4:01 PM, Heikki Linnakangas
hlinnakan...@vmware.com wrote:
 I committed the non-invasive fixes to backbranches (and master too, just to
 keep it in sync), but the attached is what I came up with for master.

 There are a couple of places in the code where we have #ifdef WIN32 code
 that uses CreateProcess with CMD /C ... directly.

1. Do we need similar handling for CreatePipe case where it directly uses
executable path such as in function pipe_read_line()?
Currently the caller of pipe_read_line() calls canonicalize_path() to change
win32 specific path, is that sufficient or do we need SYSTEMQUOTE type
of handling for it.

2.
system.c
#include assert.h
Do we really need inclusion of assert.h or this is for future use?

3. One more observation is that currently install.bat doesn't work
for such paths:
install.bat e:\PostgreSQL\master\install 1\ins@1
1\ins@1== was unexpected at this time.

4. Similar to Andrew, I also could not reproduce this problem on my
Windows system (Windows 7 64 bit)
e:\e:\PostgreSQL\master\install 1\ins@1\bin\initdb.exe -D e:
\PostgreSQL\master\Data 1
e:\e:\PostgreSQL\master\install 1\ins@1\bin\pg_ctl.exe start -D e:
\PostgreSQL\master\Data 1

Above commands work fine.

With Regards,
Amit Kapila.
EnterpriseDB: http://www.enterprisedb.com


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


[HACKERS] Fix initdb for path with whitespace and at char

2014-04-29 Thread Nikhil Deshpande
Hi,

On win32, initdb fails if it's path includes a space and at ('@')
character. E.g.

C:\C:\Program Files\user@company\Postgres\9.3\bin\initdb.exe -D c:\baz
'C:\Program' is not recognized as an internal or external command,
operable program or batch file.

Here's a patch that fixes initdb by enclosing the command string in
extra double quotes being passed to popen() (similar to system() call).

Thanks,
 Nikhil


0001-Fix-initdb-for-path-with-whitespace-and-at-char.patch
Description: Binary data

-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] Fix initdb for path with whitespace and at char

2014-04-29 Thread Heikki Linnakangas

On 04/29/2014 09:14 PM, Nikhil Deshpande wrote:

On win32, initdb fails if it's path includes a space and at ('@')
character. E.g.

C:\C:\Program Files\user@company\Postgres\9.3\bin\initdb.exe -D c:\baz
'C:\Program' is not recognized as an internal or external command,
operable program or batch file.

Here's a patch that fixes initdb by enclosing the command string in
extra double quotes being passed to popen() (similar to system() call).


This looks correct to me. popen() requires SYSTEMQUOTEs on Windows, like 
system() does. We already use SYSTEMQUOTEs in some popen() calls, like 
in pg_ctl, but initdb is missing them. get_bin_version function in 
pg_upgrade is also missing it, as is the popen() call in COPY TO/FROM 
PROGRAM command.


Is there any situation where would *not* want to wrap the command in 
SYSTEMQUOTEs? If there isn't, ISTM it would be better to create a 
wrapper function, pgwin32_popen(), which adds the quotes instead of 
sprinkling them into all callers. Even if we go around and fix all of 
the callers now, we're bound to forget it again in the future.


- Heikki


--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] Fix initdb for path with whitespace and at char

2014-04-29 Thread Tom Lane
Heikki Linnakangas hlinnakan...@vmware.com writes:
 This looks correct to me. popen() requires SYSTEMQUOTEs on Windows, like 
 system() does. We already use SYSTEMQUOTEs in some popen() calls, like 
 in pg_ctl, but initdb is missing them. get_bin_version function in 
 pg_upgrade is also missing it, as is the popen() call in COPY TO/FROM 
 PROGRAM command.

Yuck.

 Is there any situation where would *not* want to wrap the command in 
 SYSTEMQUOTEs? If there isn't, ISTM it would be better to create a 
 wrapper function, pgwin32_popen(), which adds the quotes instead of 
 sprinkling them into all callers. Even if we go around and fix all of 
 the callers now, we're bound to forget it again in the future.

We might forget to use the wrapper function too, if it has a nonstandard
name, no?  A better idea would be to redefine popen() and system() on
Windows.  It looks like we're already using a #define to redefine popen().
This approach would let us get rid of nonstandard notation for this
problem, instead of adding more.

regards, tom lane


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] Fix initdb for path with whitespace and at char

2014-04-29 Thread Amit Kapila
On Wed, Apr 30, 2014 at 3:57 AM, Tom Lane t...@sss.pgh.pa.us wrote:
 Heikki Linnakangas hlinnakan...@vmware.com writes:
 This looks correct to me. popen() requires SYSTEMQUOTEs on Windows, like
 system() does.

It seems right now  SYSTEMQUOTE is used before popen both for
Windows and non-Windows, ex. adjust_data_dir() in pg_ctl.c

 We might forget to use the wrapper function too, if it has a nonstandard
 name, no?  A better idea would be to redefine popen() and system() on
 Windows.  It looks like we're already using a #define to redefine popen().

Won't defining variant of popen just for Windows to add SYSTEMQUOTE
effect such (where currently it is used for both win and non-winows)
usage?  Also, I think we might want to remove use of SYSTEMQUOTE
before popen calls where ever it is currently used to avoid usage of the
same two times.

With Regards,
Amit Kapila.
EnterpriseDB: http://www.enterprisedb.com


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] Fix initdb for path with whitespace and at char

2014-04-29 Thread Tom Lane
Amit Kapila amit.kapil...@gmail.com writes:
 On Wed, Apr 30, 2014 at 3:57 AM, Tom Lane t...@sss.pgh.pa.us wrote:
 We might forget to use the wrapper function too, if it has a nonstandard
 name, no?  A better idea would be to redefine popen() and system() on
 Windows.  It looks like we're already using a #define to redefine popen().

 Won't defining variant of popen just for Windows to add SYSTEMQUOTE
 effect such (where currently it is used for both win and non-winows)
 usage?  Also, I think we might want to remove use of SYSTEMQUOTE
 before popen calls where ever it is currently used to avoid usage of the
 same two times.

Well, yeah: the point would be to remove SYSTEMQUOTE altogether,
probably.  Certainly the idea I'm suggesting is that we don't need any
Windows-specific notation at the call sites.

regards, tom lane


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers