losing faith.

This commit is contained in:
visionmercer 2026-06-23 12:47:05 +02:00
commit a3c7f66b2f

View file

@ -42,6 +42,8 @@ void get_absolute_path(const char* rel_path, uintptr_t abs_path_ptr, int max_len
#ifdef _WIN32 #ifdef _WIN32
static HANDLE hServerPipe = INVALID_HANDLE_VALUE; static HANDLE hServerPipe = INVALID_HANDLE_VALUE;
static OVERLAPPED oOverlap;
static BOOL fPendingIO = FALSE;
int terminkey() { int terminkey() {
if (_kbhit()) { if (_kbhit()) {
@ -86,10 +88,11 @@ int termwidth() {
} }
int ipc_init() { int ipc_init() {
// Create a regular blocking pipe, but enable FILE_FLAG_OVERLAPPED for safe async I/O
hServerPipe = CreateNamedPipe( hServerPipe = CreateNamedPipe(
"\\\\.\\pipe\\cimp_ipc", "\\\\.\\pipe\\cimp_ipc",
PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_NOWAIT, // Enable non-blocking wait mode PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
1, 1,
4096, 4096,
4096, 4096,
@ -103,6 +106,12 @@ int ipc_init() {
} }
return -1; // Other error return -1; // Other error
} }
// Initialize the overlapped structure and create an event
memset(&oOverlap, 0, sizeof(OVERLAPPED));
oOverlap.hEvent = CreateEvent(NULL, TRUE, TRUE, NULL);
fPendingIO = FALSE;
return 1; // Server mode successfully started return 1; // Server mode successfully started
} }
@ -111,27 +120,46 @@ int ipc_check_message(uintptr_t buffer_ptr, int max_len) {
char* buffer = (char*)buffer_ptr; char* buffer = (char*)buffer_ptr;
DWORD bytesRead = 0; DWORD bytesRead = 0;
// In non-blocking mode, ConnectNamedPipe returns immediately. if (!fPendingIO) {
// If a client is connected, it returns non-zero, or zero with ERROR_PIPE_CONNECTED. // Start an asynchronous listen operation
BOOL connected = ConnectNamedPipe(hServerPipe, NULL) ? if (!ConnectNamedPipe(hServerPipe, &oOverlap)) {
TRUE : (GetLastError() == ERROR_PIPE_CONNECTED); DWORD err = GetLastError();
if (err == ERROR_IO_PENDING) {
if (connected) { fPendingIO = TRUE;
DWORD bytesAvail = 0; } else if (err == ERROR_PIPE_CONNECTED) {
// Verify that data has safely populated the buffer before reading // Client already connected before we listened!
if (PeekNamedPipe(hServerPipe, NULL, 0, NULL, &bytesAvail, NULL)) { SetEvent(oOverlap.hEvent);
if (bytesAvail > 0) { fPendingIO = TRUE;
BOOL success = ReadFile(hServerPipe, buffer, max_len - 1, &bytesRead, NULL);
if (success && bytesRead > 0) {
buffer[bytesRead] = '\0';
DisconnectNamedPipe(hServerPipe); // Reset pipe state for the next command
return (int)bytesRead;
}
} }
} else { }
if (GetLastError() == ERROR_BROKEN_PIPE) { }
if (fPendingIO) {
// Check if the connection event has triggered without waiting (0ms timeout)
if (WaitForSingleObject(oOverlap.hEvent, 0) == WAIT_OBJECT_0) {
DWORD cbRet = 0;
// Connection is ready, let's see if there is data
if (GetOverlappedResult(hServerPipe, &oOverlap, &cbRet, FALSE)) {
DWORD bytesAvail = 0;
if (PeekNamedPipe(hServerPipe, NULL, 0, NULL, &bytesAvail, NULL) && bytesAvail > 0) {
// Data has arrived, read it synchronously
BOOL success = ReadFile(hServerPipe, buffer, max_len - 1, &bytesRead, NULL);
if (success && bytesRead > 0) {
buffer[bytesRead] = '\0';
// Clean up and reset for the next client connection
DisconnectNamedPipe(hServerPipe);
ResetEvent(oOverlap.hEvent);
fPendingIO = FALSE;
return (int)bytesRead;
}
}
} else {
// Client disconnected or pipe broke before sending
DisconnectNamedPipe(hServerPipe); DisconnectNamedPipe(hServerPipe);
ResetEvent(oOverlap.hEvent);
fPendingIO = FALSE;
} }
} }
} }
@ -157,9 +185,14 @@ void ipc_send_message(const char* message) {
void ipc_cleanup() { void ipc_cleanup() {
if (hServerPipe != INVALID_HANDLE_VALUE) { if (hServerPipe != INVALID_HANDLE_VALUE) {
DisconnectNamedPipe(hServerPipe);
CloseHandle(hServerPipe); CloseHandle(hServerPipe);
hServerPipe = INVALID_HANDLE_VALUE; hServerPipe = INVALID_HANDLE_VALUE;
} }
if (oOverlap.hEvent != NULL) {
CloseHandle(oOverlap.hEvent);
oOverlap.hEvent = NULL;
}
} }
void get_absolute_path(const char* rel_path, uintptr_t abs_path_ptr, int max_len) { void get_absolute_path(const char* rel_path, uintptr_t abs_path_ptr, int max_len) {