From 830fdc4b43332d1c3a36d147449ad40d23f7efde Mon Sep 17 00:00:00 2001 From: Anthony Baxter Date: Mon, 8 Apr 2002 04:42:09 +0000 Subject: [PATCH] Backport of bug 457466: "popenx() argument mangling hangs python" [Win9x only]." Can't test this myself, but MarkH sez it's ok. --- Modules/posixmodule.c | 8 ++++++- PC/w9xpopen.c | 56 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 59 insertions(+), 5 deletions(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 1733d870ce3d..f491c47aad9c 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -2422,9 +2422,15 @@ _PyPopenCreateProcess(char *cmdstring, s2 = (char *)_alloca(x); ZeroMemory(s2, x); + /* To maintain correct argument passing semantics, + we pass the command-line as it stands, and allow + quoting to be applied. w9xpopen.exe will then + use its argv vector, and re-quote the necessary + args for the ultimate child process. + */ sprintf( s2, - "%s \"%s%s%s\"", + "\"%s\" %s%s%s", modulepath, s1, s3, diff --git a/PC/w9xpopen.c b/PC/w9xpopen.c index d96d0f5e5876..31448fd81c79 100644 --- a/PC/w9xpopen.c +++ b/PC/w9xpopen.c @@ -16,9 +16,10 @@ #define WINDOWS_LEAN_AND_MEAN #include +#include const char *usage = -"This program is used by Python's os.pipe function to\n" +"This program is used by Python's os.popen function to\n" "to work around a limitation in Windows 95/98. It is\n" "not designed to be used as stand-alone program."; @@ -28,11 +29,56 @@ int main(int argc, char *argv[]) STARTUPINFO si; PROCESS_INFORMATION pi; DWORD exit_code=0; + int cmdlen = 0; + int i; + char *cmdline, *cmdlinefill; - if (argc != 2) { - MessageBox(NULL, usage, argv[0], MB_OK); + if (argc < 2) { + if (GetFileType(GetStdHandle(STD_INPUT_HANDLE))==FILE_TYPE_CHAR) + /* Attached to a console, and therefore not executed by Python + Display a message box for the inquisitive user + */ + MessageBox(NULL, usage, argv[0], MB_OK); + else { + /* Eeek - executed by Python, but args are screwed! + Write an error message to stdout so there is at + least some clue for the end user when it appears + in their output. + A message box would be hidden and blocks the app. + */ + fprintf(stdout, "Internal popen error - no args specified\n%s\n", usage); + } return 1; } + /* Build up the command-line from the args. + Args with a space are quoted, existing quotes are escaped. + To keep things simple calculating the buffer size, we assume + every character is a quote - ie, we allocate double what we need + in the worst case. As this is only double the command line passed + to us, there is a good chance this is reasonably small, so the total + allocation will almost always be < 512 bytes. + */ + for (i=1;i