diff options
Diffstat (limited to 'PC/w9xpopen.c')
-rw-r--r-- | PC/w9xpopen.c | 56 |
1 files changed, 52 insertions, 4 deletions
diff --git a/PC/w9xpopen.c b/PC/w9xpopen.c index d96d0f5..31448fd 100644 --- a/PC/w9xpopen.c +++ b/PC/w9xpopen.c @@ -16,9 +16,10 @@ #define WINDOWS_LEAN_AND_MEAN #include <windows.h> +#include <stdio.h> 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<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. */ ZeroMemory(&si, sizeof si); @@ -43,13 +89,15 @@ int main(int argc, char *argv[]) si.hStdError = GetStdHandle(STD_ERROR_HANDLE); bRet = CreateProcess( - NULL, argv[1], + NULL, cmdline, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi ); + free(cmdline); + if (bRet) { if (WaitForSingleObject(pi.hProcess, INFINITE) != WAIT_FAILED) { GetExitCodeProcess(pi.hProcess, &exit_code); |