| 
									
										
										
										
											2000-07-09 11:35:36 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * w9xpopen.c | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Serves as an intermediate stub Win32 console application to | 
					
						
							|  |  |  |  * avoid a hanging pipe when redirecting 16-bit console based | 
					
						
							|  |  |  |  * programs (including MS-DOS console based programs and batch | 
					
						
							|  |  |  |  * files) on Window 95 and Windows 98. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is to be launched with redirected standard | 
					
						
							|  |  |  |  * handles. It will launch the command line specified 16-bit | 
					
						
							|  |  |  |  * console based application in the same console, forwarding | 
					
						
							| 
									
										
										
										
											2005-07-22 21:49:32 +00:00
										 |  |  |  * its own redirected standard handles to the 16-bit child. | 
					
						
							| 
									
										
										
										
											2000-07-09 11:35:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |  * AKA solution to the problem described in KB: Q150956. | 
					
						
							|  |  |  |  */     | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-07-14 22:14:19 +00:00
										 |  |  | #define WIN32_LEAN_AND_MEAN
 | 
					
						
							| 
									
										
										
										
											2000-07-09 11:35:36 +00:00
										 |  |  | #include <windows.h>
 | 
					
						
							| 
									
										
										
										
											2002-04-03 01:47:00 +00:00
										 |  |  | #include <stdio.h>
 | 
					
						
							| 
									
										
										
										
											2002-07-14 22:14:19 +00:00
										 |  |  | #include <stdlib.h>  /* for malloc and its friends */
 | 
					
						
							| 
									
										
										
										
											2000-07-09 11:35:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | const char *usage = | 
					
						
							| 
									
										
										
										
											2002-04-15 22:57:46 +00:00
										 |  |  | "This program is used by Python's os.popen function\n" | 
					
						
							| 
									
										
										
										
											2000-07-09 11:35:36 +00:00
										 |  |  | "to work around a limitation in Windows 95/98.  It is\n" | 
					
						
							| 
									
										
										
										
											2002-04-15 22:57:46 +00:00
										 |  |  | "not designed to be used as a stand-alone program."; | 
					
						
							| 
									
										
										
										
											2000-07-09 11:35:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | int main(int argc, char *argv[]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     BOOL bRet; | 
					
						
							|  |  |  |     STARTUPINFO si; | 
					
						
							|  |  |  |     PROCESS_INFORMATION pi; | 
					
						
							| 
									
										
										
										
											2000-08-14 05:04:28 +00:00
										 |  |  |     DWORD exit_code=0; | 
					
						
							| 
									
										
											  
											
												Merged revisions 61834,61841-61842,61851-61853,61863-61864,61869-61870,61874,61889 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
  r61834 | raymond.hettinger | 2008-03-24 07:07:49 +0100 (Mon, 24 Mar 2008) | 1 line
  Tighten documentation for Random.triangular.
........
  r61841 | raymond.hettinger | 2008-03-24 09:17:39 +0100 (Mon, 24 Mar 2008) | 1 line
  Issue 2460: Make Ellipsis objects copyable.
........
  r61842 | georg.brandl | 2008-03-24 10:34:34 +0100 (Mon, 24 Mar 2008) | 2 lines
  #1700821: add a note to audioop docs about signedness of sample formats.
........
  r61851 | christian.heimes | 2008-03-24 20:57:42 +0100 (Mon, 24 Mar 2008) | 1 line
  Added quick hack for bzr
........
  r61852 | christian.heimes | 2008-03-24 20:58:17 +0100 (Mon, 24 Mar 2008) | 1 line
  Added quick hack for bzr
........
  r61853 | amaury.forgeotdarc | 2008-03-24 22:04:10 +0100 (Mon, 24 Mar 2008) | 4 lines
  Issue2469: Correct a typo I introduced at r61793: compilation error with UCS4 builds.
  All buildbots compile with UCS2...
........
  r61863 | neal.norwitz | 2008-03-25 05:17:38 +0100 (Tue, 25 Mar 2008) | 2 lines
  Fix a bunch of UnboundLocalErrors when the tests fail.
........
  r61864 | neal.norwitz | 2008-03-25 05:18:18 +0100 (Tue, 25 Mar 2008) | 2 lines
  Try to fix a bunch of compiler warnings on Win64.
........
  r61869 | neal.norwitz | 2008-03-25 07:35:10 +0100 (Tue, 25 Mar 2008) | 3 lines
  Don't try to close a non-open file.
  Don't let file removal cause the test to fail.
........
  r61870 | neal.norwitz | 2008-03-25 08:00:39 +0100 (Tue, 25 Mar 2008) | 7 lines
  Try to get this test to be more stable:
   * disable gc during the test run because we are spawning objects and there
     was an exception when calling Popen.__del__
   * Always set an alarm handler so the process doesn't exit if the test fails
     (should probably add assertions on the value of hndl_called in more places)
   * Using a negative time causes Linux to treat it as zero, so disable that test.
........
  r61874 | gregory.p.smith | 2008-03-25 08:31:28 +0100 (Tue, 25 Mar 2008) | 2 lines
  Use a 32-bit unsigned int here, a long is not needed.
........
  r61889 | georg.brandl | 2008-03-25 12:59:51 +0100 (Tue, 25 Mar 2008) | 2 lines
  Move declarations to block start.
........
											
										 
											2008-03-25 14:56:36 +00:00
										 |  |  |     size_t cmdlen = 0; | 
					
						
							| 
									
										
										
										
											2002-04-03 01:47:00 +00:00
										 |  |  |     int i; | 
					
						
							|  |  |  |     char *cmdline, *cmdlinefill; | 
					
						
							| 
									
										
										
										
											2000-07-09 11:35:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-04-03 01:47:00 +00:00
										 |  |  |     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); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2000-07-09 11:35:36 +00:00
										 |  |  |         return 1; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2002-04-03 01:47:00 +00:00
										 |  |  |     /* 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'; | 
					
						
							| 
									
										
										
										
											2000-07-09 11:35:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* Make child process use this app's standard files. */ | 
					
						
							|  |  |  |     ZeroMemory(&si, sizeof si); | 
					
						
							|  |  |  |     si.cb = sizeof si; | 
					
						
							|  |  |  |     si.dwFlags = STARTF_USESTDHANDLES; | 
					
						
							|  |  |  |     si.hStdInput = GetStdHandle(STD_INPUT_HANDLE); | 
					
						
							|  |  |  |     si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); | 
					
						
							|  |  |  |     si.hStdError = GetStdHandle(STD_ERROR_HANDLE); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bRet = CreateProcess( | 
					
						
							| 
									
										
										
										
											2002-04-03 01:47:00 +00:00
										 |  |  |         NULL, cmdline, | 
					
						
							| 
									
										
										
										
											2000-07-09 11:35:36 +00:00
										 |  |  |         NULL, NULL, | 
					
						
							|  |  |  |         TRUE, 0, | 
					
						
							|  |  |  |         NULL, NULL, | 
					
						
							|  |  |  |         &si, &pi | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-04-03 01:47:00 +00:00
										 |  |  |     free(cmdline); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-07-09 11:35:36 +00:00
										 |  |  |     if (bRet) { | 
					
						
							| 
									
										
										
										
											2000-08-14 05:04:28 +00:00
										 |  |  |         if (WaitForSingleObject(pi.hProcess, INFINITE) != WAIT_FAILED) { | 
					
						
							|  |  |  | 	    GetExitCodeProcess(pi.hProcess, &exit_code); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2000-07-09 11:35:36 +00:00
										 |  |  |         CloseHandle(pi.hProcess); | 
					
						
							|  |  |  |         CloseHandle(pi.hThread); | 
					
						
							| 
									
										
										
										
											2000-08-14 05:04:28 +00:00
										 |  |  |         return exit_code; | 
					
						
							| 
									
										
										
										
											2000-07-09 11:35:36 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 1; | 
					
						
							|  |  |  | } |