11#include " stdafx.h"
22#include " ProcessExecute.h"
33#include " WcharMbcsConverter.h"
4+ #include < fstream>
45
56/* The Console Redirection is taken from the TagsView plugin from Vitaliy Dovgan.
67 * My thanks to him for pointing me in the right direction. :)
1112#define DEFAULT_PIPE_SIZE 1
1213#define PIPE_READBUFSIZE 4096
1314
15+
1416using namespace boost ::python;
1517using namespace std ;
1618
19+
20+ const char *ProcessExecute::STREAM_NAME_STDOUT = " OUT" ;
21+ const char *ProcessExecute::STREAM_NAME_STDERR = " ERR" ;
22+
1723ProcessExecute::ProcessExecute ()
1824{
1925}
@@ -88,15 +94,19 @@ long ProcessExecute::execute(const TCHAR *commandLine, boost::python::object pyS
8894 stdoutReaderArgs.pythonFile = pyStdout;
8995 stdoutReaderArgs.stopEvent = stopEvent;
9096 stdoutReaderArgs.completedEvent = CreateEvent (NULL , FALSE , FALSE , NULL );
91- stdoutReaderArgs.streamName = " STDOUT" ;
97+ stdoutReaderArgs.streamName = STREAM_NAME_STDOUT;
98+ stdoutReaderArgs.toFile = false ;
99+
92100 stderrReaderArgs.processExecute = this ;
93101 stderrReaderArgs.hPipeRead = m_hStdErrReadPipe;
94102 stderrReaderArgs.hPipeWrite = m_hStdErrWritePipe;
95- stderrReaderArgs.stopEvent = stopEvent;
96103 stderrReaderArgs.pythonFile = pyStderr;
97- stderrReaderArgs.streamName = " STDERR" ;
98-
104+ stderrReaderArgs.stopEvent = stopEvent;
99105 stderrReaderArgs.completedEvent = CreateEvent (NULL , FALSE , FALSE , NULL );
106+ stderrReaderArgs.streamName = STREAM_NAME_STDERR;
107+ stderrReaderArgs.toFile = false ;
108+
109+
100110
101111
102112
@@ -121,13 +131,17 @@ long ProcessExecute::execute(const TCHAR *commandLine, boost::python::object pyS
121131 {
122132 throw process_start_exception (" Error creating temporary filename for output spooling" );
123133 }
124-
134+ stdoutReaderArgs.file = new fstream (tmpFilename, fstream::binary | fstream::in | fstream::out);
135+ stderrReaderArgs.file = stdoutReaderArgs.file ;
136+ /*
125137 stdoutReaderArgs.fileHandle = CreateFile(tmpFilename, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
126138 stderrReaderArgs.fileHandle = stdoutReaderArgs.fileHandle;
139+
127140 if (INVALID_HANDLE_VALUE == stdoutReaderArgs.fileHandle)
128141 {
129142 throw process_start_exception("Error opening temporary file for output spooling");
130143 }
144+ */
131145
132146
133147 }
@@ -242,11 +256,12 @@ long ProcessExecute::execute(const TCHAR *commandLine, boost::python::object pyS
242256
243257 if (spoolToFile)
244258 {
245- CloseHandle (stdoutReaderArgs.fileHandle );
246259 CloseHandle (stdoutReaderArgs.fileMutex );
247- pyStdout.attr (" write" )(boost::python::str (" File written" ));
248260
249- pyStdout.attr (" write" )(boost::python::str (const_cast <const char *>(WcharMbcsConverter::tchar2char (tmpFilename).get ())));
261+ spoolFile (stdoutReaderArgs.file , pyStdout, pyStderr);
262+
263+ stdoutReaderArgs.file ->close ();
264+ DeleteFile (tmpFilename);
250265 }
251266
252267 if (thrown)
@@ -344,20 +359,67 @@ void ProcessExecute::writeToPython(PipeReaderArgs *pipeReaderArgs, int bytesRead
344359void ProcessExecute::writeToFile (PipeReaderArgs *pipeReaderArgs, int bytesRead, char *buffer)
345360{
346361 WaitForSingleObject (pipeReaderArgs->fileMutex , INFINITE);
347- DWORD written;
348- WriteFile (pipeReaderArgs->fileHandle , pipeReaderArgs->streamName , ProcessExecute::STREAM_NAME_LENGTH, &written, NULL );
349362
350- if (written != 6 )
363+ pipeReaderArgs->file ->write (pipeReaderArgs->streamName , ProcessExecute::STREAM_NAME_LENGTH);
364+
365+
366+ if (pipeReaderArgs->file ->bad ())
351367 throw process_start_exception (" Error writing to spool file" );
352368
353369 char byteCount[20 ];
354370 _itoa_s (bytesRead, byteCount, 20 , 10 );
355371 strcat_s (byteCount, 20 , " \n " );
356372
357- WriteFile (pipeReaderArgs->fileHandle , byteCount, strlen (byteCount), &written, NULL );
358- WriteFile (pipeReaderArgs->fileHandle , buffer, bytesRead, &written, NULL );
359- if (written != bytesRead)
373+ pipeReaderArgs->file ->write (byteCount, strlen (byteCount));
374+
375+ pipeReaderArgs->file ->write (buffer, bytesRead);
376+
377+
378+ if (pipeReaderArgs->file ->bad ())
360379 throw process_start_exception (" Error writing buffer to spool file" );
361380
362381 ReleaseMutex (pipeReaderArgs->fileMutex );
382+ }
383+
384+
385+ void ProcessExecute::spoolFile (fstream* file, object pyStdout, object pyStderr)
386+ {
387+ // Rewind
388+ file->seekg (0 );
389+ char infoBuffer[30 ];
390+ char *buffer = NULL ;
391+ int bufferSize = 0 ;
392+ int bytesToRead;
393+
394+ while (!file->eof ())
395+ {
396+ file->getline (infoBuffer, 30 , ' \n ' );
397+ if (file->eof ())
398+ break ;
399+
400+ bytesToRead = atoi (infoBuffer + STREAM_NAME_LENGTH);
401+ if (bufferSize < bytesToRead || !buffer)
402+ {
403+ if (buffer)
404+ delete[] buffer;
405+
406+ bufferSize = bytesToRead + 1 ;
407+ buffer = new char [bufferSize];
408+ }
409+
410+ file->read (buffer, bytesToRead);
411+ buffer[bytesToRead] = ' \0 ' ;
412+ if (0 == strncmp (infoBuffer, STREAM_NAME_STDOUT, STREAM_NAME_LENGTH))
413+ {
414+ // Is a stdout message
415+ pyStdout.attr (" write" )(boost::python::str (const_cast <const char *>(buffer)));
416+ }
417+ else
418+ {
419+ // is a stderr message
420+ pyStderr.attr (" write" )(boost::python::str (const_cast <const char *>(buffer)));
421+ }
422+ }
423+
424+
363425}
0 commit comments