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