Skip to content

Instantly share code, notes, and snippets.

@rossy
Created March 17, 2016 08:23
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rossy/f7c54976125abd67fc63 to your computer and use it in GitHub Desktop.
Save rossy/f7c54976125abd67fc63 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <windows.h>
static CALLBACK DWORD read_thread(void *arg)
{
HANDLE pipe = arg;
OVERLAPPED ol = { .hEvent = CreateEventW(NULL, TRUE, TRUE, NULL) };
HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
char outbuf[128];
for (;;) {
DWORD r;
if (!ReadFile(pipe, outbuf, 128, NULL, &ol) && GetLastError() != ERROR_IO_PENDING)
break;
if (!GetOverlappedResult(pipe, &ol, &r, TRUE))
break;
if (!WriteConsoleA(out, outbuf, r, &(DWORD){0}, NULL) &&
!WriteFile(out, outbuf, r, &(DWORD){0}, NULL))
break;
}
CloseHandle(ol.hEvent);
return 0;
}
int wmain(int argc, wchar_t **argv)
{
if (argc < 2) {
fwprintf(stderr, L"usage: %s pipe_name\n", argv[0]);
return 1;
}
HANDLE pipe;
for (;;) {
pipe = CreateFileW(argv[1], GENERIC_READ | GENERIC_WRITE, 0, NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL);
if (pipe && pipe != INVALID_HANDLE_VALUE)
break;
if (GetLastError() != ERROR_PIPE_BUSY)
return 1;
if (!WaitNamedPipeW(argv[1], NMPWAIT_USE_DEFAULT_WAIT))
return 2;
}
HANDLE thread = CreateThread(NULL, 0, read_thread, pipe, 0, NULL);
HANDLE in = GetStdHandle(STD_INPUT_HANDLE);
OVERLAPPED ol = { .hEvent = CreateEventW(NULL, TRUE, TRUE, NULL) };
char inbuf[128];
for (;;) {
DWORD r;
if (!ReadConsoleA(in, inbuf, 128, &r, NULL) &&
!ReadFile(in, inbuf, 128, &r, NULL))
break;
if (!WriteFile(pipe, inbuf, r, NULL, &ol) && GetLastError() != ERROR_IO_PENDING)
break;
if (!GetOverlappedResult(pipe, &ol, &(DWORD){0}, TRUE))
break;
}
WaitForSingleObject(thread, INFINITE);
CloseHandle(thread);
CloseHandle(pipe);
CloseHandle(ol.hEvent);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment