Add Inter-Process Communication
This commit is contained in:
parent
46cdaf4e63
commit
19bf4b5288
4 changed files with 423 additions and 1 deletions
223
terminkey.h
223
terminkey.h
|
|
@ -3,11 +3,23 @@
|
|||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <conio.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#else
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
// Special key codes (unified across platforms)
|
||||
|
|
@ -21,8 +33,16 @@ void echooff();
|
|||
void echoon();
|
||||
int termwidth();
|
||||
|
||||
int ipc_init();
|
||||
int ipc_check_message(uintptr_t buffer_ptr, int max_len);
|
||||
void ipc_send_message(const char* message);
|
||||
void ipc_cleanup();
|
||||
void get_absolute_path(const char* rel_path, uintptr_t abs_path_ptr, int max_len);
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
static HANDLE hServerPipe = INVALID_HANDLE_VALUE;
|
||||
|
||||
int terminkey() {
|
||||
if (_kbhit()) {
|
||||
int ch = _getch();
|
||||
|
|
@ -65,8 +85,91 @@ int termwidth() {
|
|||
return -1;
|
||||
}
|
||||
|
||||
int ipc_init() {
|
||||
hServerPipe = CreateNamedPipe(
|
||||
"\\\\.\\pipe\\cimp_ipc",
|
||||
PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE,
|
||||
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_NOWAIT,
|
||||
1,
|
||||
4096,
|
||||
4096,
|
||||
0,
|
||||
NULL
|
||||
);
|
||||
if (hServerPipe == INVALID_HANDLE_VALUE) {
|
||||
DWORD err = GetLastError();
|
||||
if (err == ERROR_ACCESS_DENIED || err == ERROR_PIPE_BUSY) {
|
||||
return 0; // Already running
|
||||
}
|
||||
return -1; // Other error
|
||||
}
|
||||
ConnectNamedPipe(hServerPipe, NULL);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ipc_check_message(uintptr_t buffer_ptr, int max_len) {
|
||||
if (hServerPipe == INVALID_HANDLE_VALUE) return 0;
|
||||
|
||||
char* buffer = (char*)buffer_ptr;
|
||||
DWORD bytesRead = 0;
|
||||
BOOL connected = ConnectNamedPipe(hServerPipe, NULL) ?
|
||||
TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);
|
||||
|
||||
if (connected) {
|
||||
BOOL success = ReadFile(hServerPipe, buffer, max_len - 1, &bytesRead, NULL);
|
||||
if (success && bytesRead > 0) {
|
||||
buffer[bytesRead] = '\0';
|
||||
DisconnectNamedPipe(hServerPipe);
|
||||
ConnectNamedPipe(hServerPipe, NULL);
|
||||
return (int)bytesRead;
|
||||
}
|
||||
DisconnectNamedPipe(hServerPipe);
|
||||
ConnectNamedPipe(hServerPipe, NULL);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ipc_send_message(const char* message) {
|
||||
HANDLE hPipe = CreateFile(
|
||||
"\\\\.\\pipe\\cimp_ipc",
|
||||
GENERIC_WRITE,
|
||||
0,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
0,
|
||||
NULL
|
||||
);
|
||||
if (hPipe != INVALID_HANDLE_VALUE) {
|
||||
DWORD bytesWritten = 0;
|
||||
WriteFile(hPipe, message, strlen(message), &bytesWritten, NULL);
|
||||
CloseHandle(hPipe);
|
||||
}
|
||||
}
|
||||
|
||||
void ipc_cleanup() {
|
||||
if (hServerPipe != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(hServerPipe);
|
||||
hServerPipe = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
void get_absolute_path(const char* rel_path, uintptr_t abs_path_ptr, int max_len) {
|
||||
char* abs_path = (char*)abs_path_ptr;
|
||||
_fullpath(abs_path, rel_path, max_len);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static int server_fd = -1;
|
||||
static char socket_path[256] = "";
|
||||
|
||||
static void get_socket_path() {
|
||||
if (socket_path[0] == '\0') {
|
||||
uid_t uid = getuid();
|
||||
snprintf(socket_path, sizeof(socket_path), "/tmp/cimp_ipc_%u.sock", (unsigned int)uid);
|
||||
}
|
||||
}
|
||||
|
||||
int terminkey() {
|
||||
struct termios oldt, newt;
|
||||
int ch;
|
||||
|
|
@ -126,4 +229,124 @@ int termwidth() {
|
|||
return -1;
|
||||
}
|
||||
|
||||
int ipc_init() {
|
||||
get_socket_path();
|
||||
|
||||
int test_fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (test_fd >= 0) {
|
||||
struct sockaddr_un addr;
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sun_family = AF_UNIX;
|
||||
strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path) - 1);
|
||||
if (connect(test_fd, (struct sockaddr*)&addr, sizeof(addr)) == 0) {
|
||||
close(test_fd);
|
||||
return 0; // Already running
|
||||
}
|
||||
close(test_fd);
|
||||
}
|
||||
|
||||
unlink(socket_path);
|
||||
|
||||
server_fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (server_fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int flags = fcntl(server_fd, F_GETFL, 0);
|
||||
fcntl(server_fd, F_SETFL, flags | O_NONBLOCK);
|
||||
|
||||
struct sockaddr_un addr;
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sun_family = AF_UNIX;
|
||||
strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path) - 1);
|
||||
|
||||
if (bind(server_fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
|
||||
close(server_fd);
|
||||
server_fd = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (listen(server_fd, 5) < 0) {
|
||||
close(server_fd);
|
||||
server_fd = -1;
|
||||
unlink(socket_path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ipc_check_message(uintptr_t buffer_ptr, int max_len) {
|
||||
if (server_fd < 0) return 0;
|
||||
|
||||
char* buffer = (char*)buffer_ptr;
|
||||
int client_fd = accept(server_fd, NULL, NULL);
|
||||
if (client_fd < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int total_read = 0;
|
||||
while (total_read < max_len - 1) {
|
||||
int r = read(client_fd, buffer + total_read, max_len - 1 - total_read);
|
||||
if (r <= 0) break;
|
||||
total_read += r;
|
||||
}
|
||||
buffer[total_read] = '\0';
|
||||
close(client_fd);
|
||||
return total_read;
|
||||
}
|
||||
|
||||
void ipc_send_message(const char* message) {
|
||||
get_socket_path();
|
||||
int client_fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (client_fd < 0) return;
|
||||
|
||||
struct sockaddr_un addr;
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sun_family = AF_UNIX;
|
||||
strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path) - 1);
|
||||
|
||||
if (connect(client_fd, (struct sockaddr*)&addr, sizeof(addr)) == 0) {
|
||||
int total_written = 0;
|
||||
int len = strlen(message);
|
||||
while (total_written < len) {
|
||||
int w = write(client_fd, message + total_written, len - total_written);
|
||||
if (w <= 0) break;
|
||||
total_written += w;
|
||||
}
|
||||
}
|
||||
close(client_fd);
|
||||
}
|
||||
|
||||
void ipc_cleanup() {
|
||||
if (server_fd >= 0) {
|
||||
close(server_fd);
|
||||
server_fd = -1;
|
||||
}
|
||||
get_socket_path();
|
||||
unlink(socket_path);
|
||||
}
|
||||
|
||||
void get_absolute_path(const char* rel_path, uintptr_t abs_path_ptr, int max_len) {
|
||||
char* abs_path = (char*)abs_path_ptr;
|
||||
char resolved[PATH_MAX];
|
||||
if (realpath(rel_path, resolved) != NULL) {
|
||||
strncpy(abs_path, resolved, max_len);
|
||||
abs_path[max_len - 1] = '\0';
|
||||
} else {
|
||||
if (rel_path[0] == '/') {
|
||||
strncpy(abs_path, rel_path, max_len);
|
||||
abs_path[max_len - 1] = '\0';
|
||||
} else {
|
||||
char cwd[PATH_MAX];
|
||||
if (getcwd(cwd, sizeof(cwd)) != NULL) {
|
||||
snprintf(abs_path, max_len, "%s/%s", cwd, rel_path);
|
||||
} else {
|
||||
strncpy(abs_path, rel_path, max_len);
|
||||
abs_path[max_len - 1] = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue