losing faith.
This commit is contained in:
parent
a781ef1453
commit
a3c7f66b2f
1 changed files with 54 additions and 21 deletions
57
terminkey.h
57
terminkey.h
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -112,26 +121,45 @@ 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) {
|
||||||
|
fPendingIO = TRUE;
|
||||||
|
} else if (err == ERROR_PIPE_CONNECTED) {
|
||||||
|
// Client already connected before we listened!
|
||||||
|
SetEvent(oOverlap.hEvent);
|
||||||
|
fPendingIO = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (connected) {
|
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;
|
DWORD bytesAvail = 0;
|
||||||
// Verify that data has safely populated the buffer before reading
|
if (PeekNamedPipe(hServerPipe, NULL, 0, NULL, &bytesAvail, NULL) && bytesAvail > 0) {
|
||||||
if (PeekNamedPipe(hServerPipe, NULL, 0, NULL, &bytesAvail, NULL)) {
|
// Data has arrived, read it synchronously
|
||||||
if (bytesAvail > 0) {
|
|
||||||
BOOL success = ReadFile(hServerPipe, buffer, max_len - 1, &bytesRead, NULL);
|
BOOL success = ReadFile(hServerPipe, buffer, max_len - 1, &bytesRead, NULL);
|
||||||
if (success && bytesRead > 0) {
|
if (success && bytesRead > 0) {
|
||||||
buffer[bytesRead] = '\0';
|
buffer[bytesRead] = '\0';
|
||||||
DisconnectNamedPipe(hServerPipe); // Reset pipe state for the next command
|
|
||||||
|
// Clean up and reset for the next client connection
|
||||||
|
DisconnectNamedPipe(hServerPipe);
|
||||||
|
ResetEvent(oOverlap.hEvent);
|
||||||
|
fPendingIO = FALSE;
|
||||||
return (int)bytesRead;
|
return (int)bytesRead;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (GetLastError() == ERROR_BROKEN_PIPE) {
|
// 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) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue