[Python-Dev] Fix to allow os.popen to work from pythonw.exe
Barry Scott
barry@scottb.demon.co.uk
Thu, 6 Jul 2000 23:58:17 +0100
os.popen fails to work if pythonw.exe is used to start python. This is
true for 1.5.2 and 1.6a2.
The root cause of the problem is in the Microsoft C RTL implementation
of _popen(). _popen() will fail if there is not a valid file descriptor
for stdin or stdout.
The following replacement for WinMain.c works around the problem.
I also ensure a valid descriptor for stderr for completeness.
This was compiled and test under VC++ 6.0 SP3 on Windows 2000.
BArry
-------------------------------- WinMain.c -------------------------
/* Minimal main program -- everything is loaded from the library. */
#include <windows.h>
#include "Python.h"
#include <fcntl.h>
#include <sys/stat.h>
extern int Py_Main();
int WINAPI WinMain(
HINSTANCE hInstance, // handle to current instance
HINSTANCE hPrevInstance, // handle to previous instance
LPSTR lpCmdLine, // pointer to command line
int nCmdShow // show state of window
)
{
/*
* make sure that the C RTL has valid file descriptors for
* stdin, stdout, stderr. Use the NUL device.
* This allows popen to work under pythonw.
*
* When pythonw.exe starts the C RTL function _ioinit is called
* first. WinMain is called later hence the need to check for
* invalid handles.
*
* Note: FILE stdin, stdout, stderr do not use the file descriptors
* setup here. They are already initialised before WinMain was called.
*/
int null_file;
null_file = open( "NUL", _O_RDWR );
/* check for STDIN is invalid */
if( _get_osfhandle( 0 ) == -1 )
{ dup2( null_file, 0 ); }
/* check for STDOUT is invalid */
if( _get_osfhandle( 1 ) == -1 )
{ dup2( null_file, 1 ); }
/* check for STDERR is invalid */
if( _get_osfhandle( 2 ) == -1 )
{ dup2( null_file, 2 ); }
close( null_file );
return Py_Main(__argc, __argv);
}