[Python-checkins] CVS: python/dist/src/PC w9xpopen.c,1.2,1.2.6.1
Anthony Baxter
anthonybaxter@users.sourceforge.net
Sun, 07 Apr 2002 21:42:12 -0700
Update of /cvsroot/python/python/dist/src/PC
In directory usw-pr-cvs1:/tmp/cvs-serv18851/PC
Modified Files:
Tag: release21-maint
w9xpopen.c
Log Message:
Backport of bug
457466: "popenx() argument mangling hangs python" [Win9x only]."
Can't test this myself, but MarkH sez it's ok.
Index: w9xpopen.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/PC/w9xpopen.c,v
retrieving revision 1.2
retrieving revision 1.2.6.1
diff -C2 -d -r1.2 -r1.2.6.1
*** w9xpopen.c 14 Aug 2000 05:04:28 -0000 1.2
--- w9xpopen.c 8 Apr 2002 04:42:09 -0000 1.2.6.1
***************
*** 17,23 ****
#define WINDOWS_LEAN_AND_MEAN
#include <windows.h>
const char *usage =
! "This program is used by Python's os.pipe function to\n"
"to work around a limitation in Windows 95/98. It is\n"
"not designed to be used as stand-alone program.";
--- 17,24 ----
#define WINDOWS_LEAN_AND_MEAN
#include <windows.h>
+ #include <stdio.h>
const char *usage =
! "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.";
***************
*** 29,37 ****
PROCESS_INFORMATION pi;
DWORD exit_code=0;
! if (argc != 2) {
! MessageBox(NULL, usage, argv[0], MB_OK);
return 1;
}
/* Make child process use this app's standard files. */
--- 30,83 ----
PROCESS_INFORMATION pi;
DWORD exit_code=0;
+ int cmdlen = 0;
+ int i;
+ char *cmdline, *cmdlinefill;
! 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<argc;i++)
+ cmdlen += strlen(argv[i])*2 + 3; /* one space, maybe 2 quotes */
+ cmdline = cmdlinefill = (char *)malloc(cmdlen+1);
+ if (cmdline == NULL)
+ return -1;
+ for (i=1;i<argc;i++) {
+ const char *arglook;
+ int bQuote = strchr(argv[i], ' ') != NULL;
+ if (bQuote)
+ *cmdlinefill++ = '"';
+ /* escape quotes */
+ for (arglook=argv[i];*arglook;arglook++) {
+ if (*arglook=='"')
+ *cmdlinefill++ = '\\';
+ *cmdlinefill++ = *arglook;
+ }
+ if (bQuote)
+ *cmdlinefill++ = '"';
+ *cmdlinefill++ = ' ';
+ }
+ *cmdlinefill = '\0';
/* Make child process use this app's standard files. */
***************
*** 44,48 ****
bRet = CreateProcess(
! NULL, argv[1],
NULL, NULL,
TRUE, 0,
--- 90,94 ----
bRet = CreateProcess(
! NULL, cmdline,
NULL, NULL,
TRUE, 0,
***************
*** 50,53 ****
--- 96,101 ----
&si, &pi
);
+
+ free(cmdline);
if (bRet) {