11cb0ef41Sopenharmony_ci#include <stdlib.h>
21cb0ef41Sopenharmony_ci#include <stdio.h>
31cb0ef41Sopenharmony_ci#include <string.h>
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#include <windows.h>
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_cistatic char buf[256];
81cb0ef41Sopenharmony_cistatic DWORD read_count;
91cb0ef41Sopenharmony_cistatic DWORD write_count;
101cb0ef41Sopenharmony_cistatic HANDLE stdin_h;
111cb0ef41Sopenharmony_cistatic OVERLAPPED stdin_o;
121cb0ef41Sopenharmony_ci
131cb0ef41Sopenharmony_cistatic void die(const char* buf) {
141cb0ef41Sopenharmony_ci  fprintf(stderr, "%s\n", buf);
151cb0ef41Sopenharmony_ci  fflush(stderr);
161cb0ef41Sopenharmony_ci  exit(100);
171cb0ef41Sopenharmony_ci}
181cb0ef41Sopenharmony_ci
191cb0ef41Sopenharmony_cistatic void overlapped_read(void) {
201cb0ef41Sopenharmony_ci  if (ReadFile(stdin_h, buf, sizeof(buf), NULL, &stdin_o)) {
211cb0ef41Sopenharmony_ci    // Since we start the read operation immediately before requesting a write,
221cb0ef41Sopenharmony_ci    // it should never complete synchronously since no data would be available
231cb0ef41Sopenharmony_ci    die("read completed synchronously");
241cb0ef41Sopenharmony_ci  }
251cb0ef41Sopenharmony_ci  if (GetLastError() != ERROR_IO_PENDING) {
261cb0ef41Sopenharmony_ci    die("overlapped read failed");
271cb0ef41Sopenharmony_ci  }
281cb0ef41Sopenharmony_ci}
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_cistatic void write(const char* buf, size_t buf_size) {
311cb0ef41Sopenharmony_ci  overlapped_read();
321cb0ef41Sopenharmony_ci  DWORD write_count;
331cb0ef41Sopenharmony_ci  HANDLE stdout_h = GetStdHandle(STD_OUTPUT_HANDLE);
341cb0ef41Sopenharmony_ci  if (!WriteFile(stdout_h, buf, buf_size, &write_count, NULL)) {
351cb0ef41Sopenharmony_ci    die("overlapped write failed");
361cb0ef41Sopenharmony_ci  }
371cb0ef41Sopenharmony_ci  fprintf(stderr, "%d", write_count);
381cb0ef41Sopenharmony_ci  fflush(stderr);
391cb0ef41Sopenharmony_ci}
401cb0ef41Sopenharmony_ci
411cb0ef41Sopenharmony_ciint main(void) {
421cb0ef41Sopenharmony_ci  HANDLE event = CreateEvent(NULL, FALSE, FALSE, NULL);
431cb0ef41Sopenharmony_ci  if (event == NULL) {
441cb0ef41Sopenharmony_ci    die("failed to create event handle");
451cb0ef41Sopenharmony_ci  }
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_ci  stdin_h = GetStdHandle(STD_INPUT_HANDLE);
481cb0ef41Sopenharmony_ci  stdin_o.hEvent = event;
491cb0ef41Sopenharmony_ci
501cb0ef41Sopenharmony_ci  write("0", 1);
511cb0ef41Sopenharmony_ci
521cb0ef41Sopenharmony_ci  while (1) {
531cb0ef41Sopenharmony_ci    DWORD result = WaitForSingleObject(event, INFINITE);
541cb0ef41Sopenharmony_ci    if (result == WAIT_OBJECT_0) {
551cb0ef41Sopenharmony_ci      if (!GetOverlappedResult(stdin_h, &stdin_o, &read_count, FALSE)) {
561cb0ef41Sopenharmony_ci        die("failed to get overlapped read result");
571cb0ef41Sopenharmony_ci      }
581cb0ef41Sopenharmony_ci      if (strncmp(buf, "exit", read_count) == 0) {
591cb0ef41Sopenharmony_ci        break;
601cb0ef41Sopenharmony_ci      }
611cb0ef41Sopenharmony_ci      write(buf, read_count);
621cb0ef41Sopenharmony_ci    } else {
631cb0ef41Sopenharmony_ci      char emsg[0xfff];
641cb0ef41Sopenharmony_ci      int ecode = GetLastError();
651cb0ef41Sopenharmony_ci      DWORD rv = FormatMessage(
661cb0ef41Sopenharmony_ci          FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
671cb0ef41Sopenharmony_ci          NULL,
681cb0ef41Sopenharmony_ci          ecode,
691cb0ef41Sopenharmony_ci          MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
701cb0ef41Sopenharmony_ci          (LPSTR)emsg,
711cb0ef41Sopenharmony_ci          sizeof(emsg),
721cb0ef41Sopenharmony_ci          NULL);
731cb0ef41Sopenharmony_ci      if (rv > 0) {
741cb0ef41Sopenharmony_ci        snprintf(emsg, sizeof(emsg),
751cb0ef41Sopenharmony_ci            "WaitForSingleObject failed. Error %d (%s)", ecode, emsg);
761cb0ef41Sopenharmony_ci      } else {
771cb0ef41Sopenharmony_ci        snprintf(emsg, sizeof(emsg),
781cb0ef41Sopenharmony_ci            "WaitForSingleObject failed. Error %d", ecode);
791cb0ef41Sopenharmony_ci      }
801cb0ef41Sopenharmony_ci      die(emsg);
811cb0ef41Sopenharmony_ci    }
821cb0ef41Sopenharmony_ci  }
831cb0ef41Sopenharmony_ci
841cb0ef41Sopenharmony_ci  return 0;
851cb0ef41Sopenharmony_ci}
86