Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using overlapped IO for console input?

I'm attempting to use overlapped IO to read input from the console by opening CONIN$ with the FILE_FLAG_OVERLAPPED flag. However, ReadFile blocks when I use it, even with an OVERLAPPED parameter.

I've read some posts reporting that this is a Windows 7 bug. I am using 7 so that could be possible.

Here's the code I'm using:

// Create a console window
AllocConsole();
AttachConsole(GetProcessId(GetModuleHandle(NULL)));

HANDLE overlappedConsoleIn = CreateFile(L"CONIN$",
                              GENERIC_READ,
                              FILE_SHARE_READ,
                              NULL,
                              OPEN_EXISTING,
                              FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING,
                              NULL);

// Set up the console to work with stdio
FILE *consoleOut = _fdopen(_open_osfhandle((long)GetStdHandle(STD_OUTPUT_HANDLE), _O_TEXT), "w");
FILE *consoleIn = _fdopen(_open_osfhandle((long)overlappedConsoleIn, _O_TEXT), "r");

*stdout = *consoleOut;
*stdin = *consoleIn;

setvbuf(consoleOut, NULL, _IONBF, 0);
setvbuf(consoleIn, NULL, _IONBF, 0);

std::ios::sync_with_stdio();

// Create a completion event
HANDLE inputEvent = CreateEvent(NULL, true, false, NULL);

BYTE inputBuffer[128];

OVERLAPPED overlappedData;
overlappedData.Offset = 0;
overlappedData.OffsetHigh = 0;
overlappedData.hEvent = inputEvent;

DWORD numBytesRead = 0;

// Asynchronously read from console
ReadFile(overlappedConsoleIn, inputBuffer, 128, &numBytesRead, &overlappedData);

while(true)
{
    if(WaitForSingleObject(inputEvent, 0) == WAIT_OBJECT_0)
    {
        std::cout << "input has been received" << std::endl;
    }
    std::cout << "doing something" << std::endl;
}
like image 412
Connor Worley Avatar asked Dec 29 '10 05:12

Connor Worley


1 Answers

When you open CONIN$ or CONOUT$ the parameter dwFlagsAndAttributes is ignored (in the documentation of the CreateFile function is a complete description about how to open the console). If you like to read the console asynchronously, you can pass the handle returned by CreateFile directly to the WaitForSingleObject function and if any Console event is pending this handle would be signaled, with the function ReadConsoleInput do you read the pending events. Here is the complete documentation of how to use the console in windows.

like image 65
Luis G. Costantini R. Avatar answered Nov 12 '22 20:11

Luis G. Costantini R.