Redirect stdout to a buffer [Errno 9]

Gabriel Genellina gagsl-py2 at yahoo.com.ar
Tue Nov 17 06:51:07 CET 2009


En Mon, 16 Nov 2009 18:04:21 -0300, Ecir Hana <ecir.hana at gmail.com>  
escribió:
> On Nov 16, 7:21 pm, "Gabriel Genellina" <gagsl-... at yahoo.com.ar>
> wrote:
>> En Mon, 16 Nov 2009 14:17:52 -0300, Ecir Hana <ecir.h... at gmail.com>  
>> escribió:
>>
>> >> I'm trying to write a simple Win32 app, which may run some Python
>> >> scripts. Since it is a Windows GUI app, I would like to redirect all
>> >> output (Python print, C printf, fprinf stderr, ...) to a text area
>> >> inside the app. In other words, I'm trying to log all the output from
>> >> the app (C, Python) to a window. So far, this works for C printf():
>> >> [...]
>
> thanks for the reply!

Sorry, my earlier code was not working as I expected; I wrongly assumed  
the output was being redirected but that was not the case.
The version below ("set paranoid mode on") does redirect printf(),  
fwrite(stdout,...), write(1,...), WriteFile(consolehandle,...), all those  
calls in C, but fails in Python with IOError: [Errno 9] Bad file  
descriptor.
I'm unable to figure out *where* it fails just by reading the Python  
source; one should set a breakpoint in python26.dll to see what actually  
happens.

> However, please, could you tell me how many bytes it read here:
>
> ReadFile(hReadPipe, buffer, 19, &nr, NULL);

The code below now reads from the pipe everything that has been written --  
except from Python :(

<code>
#include <windows.h>
#include <stdio.h>
#include <fcntl.h>
#include "Python.h"

int error(char* lpszText)
{
     LPVOID lpMsgBuf;
     DWORD lasterror = GetLastError();

     FormatMessage(
         FORMAT_MESSAGE_ALLOCATE_BUFFER |
         FORMAT_MESSAGE_FROM_SYSTEM |
         FORMAT_MESSAGE_IGNORE_INSERTS,
         NULL,
         lasterror,
         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
         (LPTSTR) &lpMsgBuf,
         0, NULL );
     fprintf(stderr,
         "%s: error %d: %s",
         lpszText, lasterror, lpMsgBuf);
     LocalFree(lpMsgBuf);
     return 1;
}

int main()
{
   HANDLE hReadPipe, hWritePipe;
   DWORD nr, nw;
   char buffer[100];
   int fd, i;
   BOOL bResult;

   if (!CreatePipe(
     &hReadPipe,
     &hWritePipe,
     NULL,
         0))
     return error("cannot create pipe");
   if (!SetStdHandle(STD_OUTPUT_HANDLE, hWritePipe))
     return error("SetStdHandle");

   // this was missing in previous version
   fd = _open_osfhandle((intptr_t)hWritePipe, _O_TEXT);
   if (fd==-1) return error("_open_osfhandle");
   if (_dup2(fd, 1)!=0) return error("dup2");

   if (!WriteFile(hWritePipe, "WriteFile(pipe)\n", 16, &nr, NULL)) return  
error("WriteFile(pipe)");
   if (!WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), "WriteFile(stdout)\n",  
18, &nr, NULL)) return error("WriteFile(stdout)");
   fputs("fputs from C\n", stdout);
   if (fwrite("fwrite from C\n", 1, 14, stdout)!=14) return  
error("fwrite!=14");
   if (write(1, "write from C\n", 13)<0) return error("write");
   fflush(stdout);

   fprintf(stderr, "before Python\n");
   Py_Initialize();
   PyRun_SimpleString("import sys;sys.stdout.write('from Python\\n')\n");
   Py_Finalize();

   fprintf(stderr, "before flush 2\n");
   fflush(stdout);

   fprintf(stderr, "before close pipe w\n");
   if (!CloseHandle(hWritePipe)) return error("CloseHandle(hWritePipe)");
   fprintf(stderr, "before close STDOUT Handle\n");
   if (!CloseHandle(GetStdHandle(STD_OUTPUT_HANDLE))) return  
error("CloseHandle(STDOUT)");
   fprintf(stderr, "before read pipe\n");
   // read one char at a time...
   for (i = 0; i<sizeof(buffer); i++) {
     bResult = ReadFile(hReadPipe, &buffer[i], 1, &nr, NULL);
     if ((!bResult) || (nr==0))
         break;
   }
   buffer[i]='\0';
   fprintf(stderr, "before close pipe r\n");
   if (!CloseHandle(hReadPipe)) return error("CloseHandle(hReadPipe)");
   fprintf(stderr, "==========\nnread=%d\n%s\n", i, buffer);
   return 0;
}
</code>


-- 
Gabriel Genellina




More information about the Python-list mailing list