|
40 | 40 | #include "libc/nt/enum/fileflagandattributes.h"
|
41 | 41 | #include "libc/nt/enum/filesharemode.h"
|
42 | 42 | #include "libc/nt/errors.h"
|
| 43 | +#include "libc/nt/events.h" |
43 | 44 | #include "libc/nt/files.h"
|
44 | 45 | #include "libc/nt/process.h"
|
45 | 46 | #include "libc/nt/runtime.h"
|
| 47 | +#include "libc/nt/struct/overlapped.h" |
46 | 48 | #include "libc/nt/thunk/msabi.h"
|
47 | 49 | #include "libc/runtime/internal.h"
|
48 | 50 | #include "libc/runtime/memtrack.internal.h"
|
|
113 | 115 | }
|
114 | 116 |
|
115 | 117 | // clang-format off
|
| 118 | +__msabi extern typeof(CloseHandle) *const __imp_CloseHandle; |
| 119 | +__msabi extern typeof(CreateEvent) *const __imp_CreateEventW; |
116 | 120 | __msabi extern typeof(CreateFile) *const __imp_CreateFileW;
|
117 | 121 | __msabi extern typeof(DuplicateHandle) *const __imp_DuplicateHandle;
|
118 | 122 | __msabi extern typeof(GetEnvironmentVariable) *const __imp_GetEnvironmentVariableW;
|
119 | 123 | __msabi extern typeof(GetLastError) *const __imp_GetLastError;
|
| 124 | +__msabi extern typeof(GetOverlappedResult) *const __imp_GetOverlappedResult; |
120 | 125 | __msabi extern typeof(GetStdHandle) *const __imp_GetStdHandle;
|
121 | 126 | __msabi extern typeof(SetLastError) *const __imp_SetLastError;
|
122 | 127 | __msabi extern typeof(WriteFile) *const __imp_WriteFile;
|
@@ -283,7 +288,7 @@ privileged long kloghandle(void) {
|
283 | 288 | hand = __imp_CreateFileW(
|
284 | 289 | path, kNtFileAppendData,
|
285 | 290 | kNtFileShareRead | kNtFileShareWrite | kNtFileShareDelete, 0,
|
286 |
| - kNtOpenAlways, kNtFileAttributeNormal, 0); |
| 291 | + kNtOpenAlways, kNtFileAttributeNormal | kNtFileFlagOverlapped, 0); |
287 | 292 | } else {
|
288 | 293 | hand = -1; // KPRINTF_LOG was empty string or too long
|
289 | 294 | }
|
@@ -359,19 +364,27 @@ privileged void _klog_serial(const char *b, size_t n) {
|
359 | 364 |
|
360 | 365 | privileged void klog(const char *b, size_t n) {
|
361 | 366 | #ifdef __x86_64__
|
362 |
| - int e; |
363 | 367 | long h;
|
364 | 368 | uint32_t wrote;
|
365 | 369 | long rax, rdi, rsi, rdx;
|
366 | 370 | if ((h = kloghandle()) == -1) {
|
367 | 371 | return;
|
368 | 372 | }
|
369 | 373 | if (IsWindows()) {
|
370 |
| - e = __imp_GetLastError(); |
371 |
| - if (!__imp_WriteFile(h, b, n, &wrote, 0)) { |
372 |
| - __imp_SetLastError(e); |
373 |
| - __klog_handle = 0; |
| 374 | + bool32 ok; |
| 375 | + intptr_t ev; |
| 376 | + int e = __imp_GetLastError(); |
| 377 | + if ((ev = __imp_CreateEventW(0, 0, 0, 0))) { |
| 378 | + struct NtOverlapped overlap = {.hEvent = ev}; |
| 379 | + ok = !!__imp_WriteFile(h, b, n, 0, &overlap); |
| 380 | + if (!ok && __imp_GetLastError() == kNtErrorIoPending) |
| 381 | + ok = true; |
| 382 | + ok &= !!__imp_GetOverlappedResult(h, &overlap, &wrote, true); |
| 383 | + if (!ok) |
| 384 | + __klog_handle = 0; |
| 385 | + __imp_CloseHandle(ev); |
374 | 386 | }
|
| 387 | + __imp_SetLastError(e); |
375 | 388 | } else if (IsMetal()) {
|
376 | 389 | if (_weaken(_klog_vga)) {
|
377 | 390 | _weaken(_klog_vga)(b, n);
|
|
0 commit comments