mirror of
https://github.com/Ylianst/MeshAgent
synced 2025-12-16 08:13:30 +00:00
1. Fixed Posix bug where invalid FD can cause other FD to not get serviced, and/or cause 100% CPU spike
2. Added Caps/Num/Scroll support to macOS KVM.
This commit is contained in:
@@ -384,3 +384,21 @@ char* crashMemory = ILib_POSIX_InstallCrashHandler(argv[0]);
|
|||||||
#endif
|
#endif
|
||||||
return retCode;
|
return retCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern void* gILibChain;
|
||||||
|
void _fdsnap()
|
||||||
|
{
|
||||||
|
char val[] = "require('ChainViewer').getSnapshot().then(function(c) { console.log(c); console.log(require('ChainViewer').getTimerInfo()); });";
|
||||||
|
duk_eval_string_noresult(agentHost->meshCoreCtx, val);
|
||||||
|
}
|
||||||
|
void _fdsnap2()
|
||||||
|
{
|
||||||
|
char val[] = "console.setDestination(console.Destinations.LOGFILE);require('ChainViewer').getSnapshot().then(function(c) { console.log(c); console.log(require('ChainViewer').getTimerInfo()); });";
|
||||||
|
duk_eval_string_noresult(agentHost->meshCoreCtx, val);
|
||||||
|
}
|
||||||
|
void _timerinfo()
|
||||||
|
{
|
||||||
|
char *s = ILibChain_GetMetadataForTimers(gILibChain);
|
||||||
|
printf("%s\n", s);
|
||||||
|
ILibMemory_Free(s);
|
||||||
|
}
|
||||||
@@ -236,9 +236,42 @@ void MouseAction(double absX, double absY, int button, short wheel)
|
|||||||
if (source != NULL) CFRelease(source);
|
if (source != NULL) CFRelease(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern int set_kbd_state(int state);
|
||||||
|
extern int get_kbd_state();
|
||||||
void KeyAction(unsigned char vk, int up)
|
void KeyAction(unsigned char vk, int up)
|
||||||
{
|
{
|
||||||
//ILIBLOGMESSAGEX("NORMAL: %u [%d]", vk, up);
|
//ILIBLOGMESSAGEX("NORMAL: %u [%d]", vk, up);
|
||||||
|
if (up == 4) { up = 0; }
|
||||||
|
|
||||||
|
if (up && (vk == 0x14 || vk == 0x90 || vk == 0x91))
|
||||||
|
{
|
||||||
|
int state = get_kbd_state();
|
||||||
|
|
||||||
|
switch (vk)
|
||||||
|
{
|
||||||
|
case 0x14: // CAPS LOCK
|
||||||
|
state = set_kbd_state(state ^ 4);
|
||||||
|
break;
|
||||||
|
case 0x90: // NUM LOCK
|
||||||
|
state = set_kbd_state(state ^ 1);
|
||||||
|
break;
|
||||||
|
case 0x91: // SCROLL LOCK
|
||||||
|
state = set_kbd_state(state ^ 2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char *buffer = ILibMemory_SmartAllocate(5);
|
||||||
|
((unsigned short*)buffer)[0] = (unsigned short)htons((unsigned short)MNG_KVM_KEYSTATE); // Write the type
|
||||||
|
((unsigned short*)buffer)[1] = (unsigned short)htons((unsigned short)5); // Write the size
|
||||||
|
buffer[4] = (unsigned char)get_kbd_state();
|
||||||
|
|
||||||
|
// Write the reply to the pipe.
|
||||||
|
ILibQueue_Lock(g_messageQ);
|
||||||
|
ILibQueue_EnQueue(g_messageQ, buffer);
|
||||||
|
ILibQueue_UnLock(g_messageQ);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
CGKeyCode keycode;
|
CGKeyCode keycode;
|
||||||
|
|||||||
@@ -21,11 +21,15 @@ limitations under the License.
|
|||||||
#include "../../../microstack/ILibAsyncSocket.h"
|
#include "../../../microstack/ILibAsyncSocket.h"
|
||||||
#include "../../../microstack/ILibAsyncServerSocket.h"
|
#include "../../../microstack/ILibAsyncServerSocket.h"
|
||||||
#include "../../../microstack/ILibProcessPipe.h"
|
#include "../../../microstack/ILibProcessPipe.h"
|
||||||
|
#include <IOKit/IOKitLib.h>
|
||||||
|
#include <IOKit/hidsystem/IOHIDLib.h>
|
||||||
|
#include <IOKit/hidsystem/IOHIDParameter.h>
|
||||||
#include <CoreFoundation/CoreFoundation.h>
|
#include <CoreFoundation/CoreFoundation.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
|
|
||||||
|
|
||||||
int KVM_Listener_FD = -1;
|
int KVM_Listener_FD = -1;
|
||||||
#define KVM_Listener_Path "/usr/local/mesh_services/meshagent/kvm"
|
#define KVM_Listener_Path "/usr/local/mesh_services/meshagent/kvm"
|
||||||
#if defined(_TLSLOG)
|
#if defined(_TLSLOG)
|
||||||
@@ -92,7 +96,7 @@ ILibQueue g_messageQ;
|
|||||||
|
|
||||||
|
|
||||||
#define KvmDebugLog(...)
|
#define KvmDebugLog(...)
|
||||||
//#define KvmDebugLog(...) printf(__VA_ARGS__); //if (logfile != NULL) fprintf(logfile, __VA_ARGS__);
|
//#define KvmDebugLog(...) printf(__VA_ARGS__); if (logfile != NULL) fprintf(logfile, __VA_ARGS__);
|
||||||
//#define KvmDebugLog(x) if (logenabled) printf(x);
|
//#define KvmDebugLog(x) if (logenabled) printf(x);
|
||||||
//#define KvmDebugLog(x) if (logenabled) fprintf(logfile, "Writing from slave in kvm_send_resolution\n");
|
//#define KvmDebugLog(x) if (logenabled) fprintf(logfile, "Writing from slave in kvm_send_resolution\n");
|
||||||
|
|
||||||
@@ -129,6 +133,138 @@ void kvm_send_resolution()
|
|||||||
|
|
||||||
#define BUFSIZE 65535
|
#define BUFSIZE 65535
|
||||||
|
|
||||||
|
int set_kbd_state(int input_state)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
kern_return_t kr;
|
||||||
|
io_service_t ios;
|
||||||
|
io_connect_t ioc;
|
||||||
|
CFMutableDictionaryRef mdict;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
mdict = IOServiceMatching(kIOHIDSystemClass);
|
||||||
|
ios = IOServiceGetMatchingService(kIOMasterPortDefault, (CFDictionaryRef)mdict);
|
||||||
|
if (!ios)
|
||||||
|
{
|
||||||
|
if (mdict)
|
||||||
|
{
|
||||||
|
CFRelease(mdict);
|
||||||
|
}
|
||||||
|
ILIBLOGMESSAGEX("IOServiceGetMatchingService() failed\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
kr = IOServiceOpen(ios, mach_task_self(), kIOHIDParamConnectType, &ioc);
|
||||||
|
IOObjectRelease(ios);
|
||||||
|
if (kr != KERN_SUCCESS)
|
||||||
|
{
|
||||||
|
ILIBLOGMESSAGEX("IOServiceOpen() failed: %x\n", kr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set CAPSLOCK
|
||||||
|
kr = IOHIDSetModifierLockState(ioc, kIOHIDCapsLockState, (input_state & 4) == 4);
|
||||||
|
if (kr != KERN_SUCCESS)
|
||||||
|
{
|
||||||
|
IOServiceClose(ioc);
|
||||||
|
ILIBLOGMESSAGEX("IOHIDGetModifierLockState() failed: %x\n", kr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set NUMLOCK
|
||||||
|
kr = IOHIDSetModifierLockState(ioc, kIOHIDNumLockState, (input_state & 1) == 1);
|
||||||
|
if (kr != KERN_SUCCESS)
|
||||||
|
{
|
||||||
|
IOServiceClose(ioc);
|
||||||
|
ILIBLOGMESSAGEX("IOHIDGetModifierLockState() failed: %x\n", kr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CAPSLOCK_QUERY
|
||||||
|
bool state;
|
||||||
|
kr = IOHIDGetModifierLockState(ioc, kIOHIDCapsLockState, &state);
|
||||||
|
if (kr != KERN_SUCCESS)
|
||||||
|
{
|
||||||
|
IOServiceClose(ioc);
|
||||||
|
ILIBLOGMESSAGEX("IOHIDGetModifierLockState() failed: %x\n", kr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ret |= (state << 2);
|
||||||
|
|
||||||
|
// NUMLOCK_QUERY
|
||||||
|
kr = IOHIDGetModifierLockState(ioc, kIOHIDNumLockState, &state);
|
||||||
|
if (kr != KERN_SUCCESS)
|
||||||
|
{
|
||||||
|
IOServiceClose(ioc);
|
||||||
|
ILIBLOGMESSAGEX("IOHIDGetModifierLockState() failed: %x\n", kr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ret |= state;
|
||||||
|
|
||||||
|
IOServiceClose(ioc);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
int get_kbd_state()
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
kern_return_t kr;
|
||||||
|
io_service_t ios;
|
||||||
|
io_connect_t ioc;
|
||||||
|
CFMutableDictionaryRef mdict;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
mdict = IOServiceMatching(kIOHIDSystemClass);
|
||||||
|
ios = IOServiceGetMatchingService(kIOMasterPortDefault, (CFDictionaryRef)mdict);
|
||||||
|
if (!ios)
|
||||||
|
{
|
||||||
|
if (mdict)
|
||||||
|
{
|
||||||
|
CFRelease(mdict);
|
||||||
|
}
|
||||||
|
ILIBLOGMESSAGEX("IOServiceGetMatchingService() failed\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
kr = IOServiceOpen(ios, mach_task_self(), kIOHIDParamConnectType, &ioc);
|
||||||
|
IOObjectRelease(ios);
|
||||||
|
if (kr != KERN_SUCCESS)
|
||||||
|
{
|
||||||
|
ILIBLOGMESSAGEX("IOServiceOpen() failed: %x\n", kr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CAPSLOCK_QUERY
|
||||||
|
bool state;
|
||||||
|
kr = IOHIDGetModifierLockState(ioc, kIOHIDCapsLockState, &state);
|
||||||
|
if (kr != KERN_SUCCESS)
|
||||||
|
{
|
||||||
|
IOServiceClose(ioc);
|
||||||
|
ILIBLOGMESSAGEX("IOHIDGetModifierLockState() failed: %x\n", kr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ret |= (state << 2);
|
||||||
|
|
||||||
|
// NUMLOCK_QUERY
|
||||||
|
kr = IOHIDGetModifierLockState(ioc, kIOHIDNumLockState, &state);
|
||||||
|
if (kr != KERN_SUCCESS)
|
||||||
|
{
|
||||||
|
IOServiceClose(ioc);
|
||||||
|
ILIBLOGMESSAGEX("IOHIDGetModifierLockState() failed: %x\n", kr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ret |= state;
|
||||||
|
|
||||||
|
IOServiceClose(ioc);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int kvm_init()
|
int kvm_init()
|
||||||
{
|
{
|
||||||
ILibCriticalLogFilename = "KVMSlave.log";
|
ILibCriticalLogFilename = "KVMSlave.log";
|
||||||
@@ -157,9 +293,17 @@ int kvm_init()
|
|||||||
if (SCREEN_HEIGHT % TILE_HEIGHT) { TILE_HEIGHT_COUNT++; }
|
if (SCREEN_HEIGHT % TILE_HEIGHT) { TILE_HEIGHT_COUNT++; }
|
||||||
|
|
||||||
kvm_send_resolution();
|
kvm_send_resolution();
|
||||||
|
|
||||||
reset_tile_info(old_height_count);
|
reset_tile_info(old_height_count);
|
||||||
|
|
||||||
|
unsigned char *buffer = ILibMemory_SmartAllocate(5);
|
||||||
|
((unsigned short*)buffer)[0] = (unsigned short)htons((unsigned short)MNG_KVM_KEYSTATE); // Write the type
|
||||||
|
((unsigned short*)buffer)[1] = (unsigned short)htons((unsigned short)5); // Write the size
|
||||||
|
buffer[4] = (unsigned char)get_kbd_state();
|
||||||
|
|
||||||
|
// Write the reply to the pipe.
|
||||||
|
ILibQueue_Lock(g_messageQ);
|
||||||
|
ILibQueue_EnQueue(g_messageQ, buffer);
|
||||||
|
ILibQueue_UnLock(g_messageQ);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -99,6 +99,9 @@ limitations under the License.
|
|||||||
#define PORTNUMBERRANGE 15000
|
#define PORTNUMBERRANGE 15000
|
||||||
#define UPNP_MAX_WAIT 86400 // 24 Hours
|
#define UPNP_MAX_WAIT 86400 // 24 Hours
|
||||||
|
|
||||||
|
extern void _fdsnap();
|
||||||
|
extern void _fdsnap2();
|
||||||
|
|
||||||
#ifdef _REMOTELOGGINGSERVER
|
#ifdef _REMOTELOGGINGSERVER
|
||||||
#include "ILibWebServer.h"
|
#include "ILibWebServer.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -3231,6 +3234,9 @@ char *ILibChain_GetMetaDataFromDescriptorSetEx(void *chain, fd_set *inr, fd_set
|
|||||||
int f, r;
|
int f, r;
|
||||||
size_t tmp;
|
size_t tmp;
|
||||||
size_t buflen = 0;
|
size_t buflen = 0;
|
||||||
|
struct timeval tv = { 0 };
|
||||||
|
fd_set temp_readset, temp_writeset, temp_errorset;
|
||||||
|
int bad;
|
||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
@@ -3286,13 +3292,25 @@ char *ILibChain_GetMetaDataFromDescriptorSetEx(void *chain, fd_set *inr, fd_set
|
|||||||
{
|
{
|
||||||
if (FD_ISSET(f, &readset) || FD_ISSET(f, &writeset) || FD_ISSET(f, &errorset))
|
if (FD_ISSET(f, &readset) || FD_ISSET(f, &writeset) || FD_ISSET(f, &errorset))
|
||||||
{
|
{
|
||||||
|
bad = 0;
|
||||||
|
if (!FD_ISSET(f, inr) && !FD_ISSET(f, inw) && !FD_ISSET(f, ine))
|
||||||
|
{
|
||||||
|
FD_ZERO(&temp_readset);
|
||||||
|
FD_ZERO(&temp_writeset);
|
||||||
|
FD_ZERO(&temp_errorset);
|
||||||
|
if (FD_ISSET(f, &readset)) { FD_SET(f, &temp_readset); }
|
||||||
|
if (FD_ISSET(f, &writeset)) { FD_SET(f, &temp_writeset); }
|
||||||
|
if (FD_ISSET(f, &errorset)) { FD_SET(f, &temp_errorset); }
|
||||||
|
bad = select(FD_SETSIZE, &temp_readset, &temp_writeset, &temp_errorset, &tv) == -1 ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (retStr == NULL)
|
if (retStr == NULL)
|
||||||
{
|
{
|
||||||
buflen += snprintf(NULL, 0, " FD[%d] (R: %d, W: %d, E: %d) => %s\n", f, FD_ISSET(f, inr), FD_ISSET(f, inw), FD_ISSET(f, ine), ((ILibChain_Link*)module)->QueryHandler != NULL ? ((ILibChain_Link*)module)->QueryHandler(chain, module, f, &tmp) : ((ILibChain_Link*)module)->MetaData);
|
buflen += snprintf(NULL, 0, "%sFD[%d] (R: %d, W: %d, E: %d) => %s\n", bad==0?"":"*", f, FD_ISSET(f, inr), FD_ISSET(f, inw), FD_ISSET(f, ine), ((ILibChain_Link*)module)->QueryHandler != NULL ? ((ILibChain_Link*)module)->QueryHandler(chain, module, f, &tmp) : ((ILibChain_Link*)module)->MetaData);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
r = sprintf_s(retStr + len, ILibMemory_Size(retStr) - len, " FD[%d] (R: %d, W: %d, E: %d) => %s\n", f, FD_ISSET(f, inr), FD_ISSET(f, inw), FD_ISSET(f, ine), ((ILibChain_Link*)module)->QueryHandler != NULL ? ((ILibChain_Link*)module)->QueryHandler(chain, module, f, &tmp) : ((ILibChain_Link*)module)->MetaData);
|
r = sprintf_s(retStr + len, ILibMemory_Size(retStr) - len, " %sFD[%d] (R: %d, W: %d, E: %d) => %s\n", bad == 0 ? "" : "*", f, FD_ISSET(f, inr), FD_ISSET(f, inw), FD_ISSET(f, ine), ((ILibChain_Link*)module)->QueryHandler != NULL ? ((ILibChain_Link*)module)->QueryHandler(chain, module, f, &tmp) : ((ILibChain_Link*)module)->MetaData);
|
||||||
if (r > 0) { len += r; }
|
if (r > 0) { len += r; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3386,6 +3404,7 @@ char *ILibChain_GetMetadataForTimers(void *chain)
|
|||||||
double ex = (double)(Temp->ExpirationTick - current);
|
double ex = (double)(Temp->ExpirationTick - current);
|
||||||
char *units = "milliseconds";
|
char *units = "milliseconds";
|
||||||
|
|
||||||
|
if (ex < 0) { ex = 0; }
|
||||||
if (ex > 1000)
|
if (ex > 1000)
|
||||||
{
|
{
|
||||||
ex = ex / 1000;
|
ex = ex / 1000;
|
||||||
@@ -3959,12 +3978,12 @@ ILibExportMethod void ILibStartChain(void *Chain)
|
|||||||
ILibChain_Link *module;
|
ILibChain_Link *module;
|
||||||
ILibChain_Link_Hook *nodeHook;
|
ILibChain_Link_Hook *nodeHook;
|
||||||
|
|
||||||
fd_set readset;
|
fd_set readset, tmp_readset;
|
||||||
fd_set errorset;
|
fd_set errorset, tmp_errorset;
|
||||||
fd_set writeset;
|
fd_set writeset, tmp_writeset;
|
||||||
|
|
||||||
struct timeval tv;
|
struct timeval tv, tmp_tv = { 0 };
|
||||||
int slct;
|
int slct, f;
|
||||||
int vX;
|
int vX;
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -4072,11 +4091,35 @@ ILibExportMethod void ILibStartChain(void *Chain)
|
|||||||
if (slct == -1)
|
if (slct == -1)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// If the select simply timed out, we need to clear these sets
|
// One of the descriptors was invalid
|
||||||
//
|
//
|
||||||
FD_ZERO(&readset);
|
for (f = 0; f < FD_SETSIZE; ++f)
|
||||||
FD_ZERO(&writeset);
|
{
|
||||||
FD_ZERO(&errorset);
|
if (FD_ISSET(f, &readset) || FD_ISSET(f, &writeset) || FD_ISSET(f, &errorset))
|
||||||
|
{
|
||||||
|
FD_ZERO(&tmp_readset);
|
||||||
|
FD_ZERO(&tmp_writeset);
|
||||||
|
FD_ZERO(&tmp_errorset);
|
||||||
|
if (FD_ISSET(f, &readset)) { FD_SET(f, &tmp_readset); }
|
||||||
|
if (FD_ISSET(f, &writeset)) { FD_SET(f, &tmp_writeset); }
|
||||||
|
if (FD_ISSET(f, &errorset)) { FD_SET(f, &tmp_errorset); }
|
||||||
|
if (select(FD_SETSIZE, &tmp_readset, &tmp_writeset, &tmp_errorset, &tmp_tv) == -1)
|
||||||
|
{
|
||||||
|
// Found the bad descriptor... Let's dump it
|
||||||
|
FD_CLR(f, &readset);
|
||||||
|
FD_CLR(f, &writeset);
|
||||||
|
FD_CLR(f, &errorset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((slct = select(FD_SETSIZE, &readset, &writeset, &errorset, &tv)) == -1)
|
||||||
|
{
|
||||||
|
// Something went wrong, so we have no other choice but to clear the sets
|
||||||
|
FD_ZERO(&readset);
|
||||||
|
FD_ZERO(&writeset);
|
||||||
|
FD_ZERO(&errorset);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
@@ -7565,6 +7608,8 @@ ILibLifeTime_Token ILibLifeTime_AddEx4(void *LifetimeMonitorObject, void *data,
|
|||||||
if (Destroy != NULL) { Destroy(data); }
|
if (Destroy != NULL) { Destroy(data); }
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
ILibLifeTime_Remove(LifetimeMonitorObject, data);
|
||||||
|
|
||||||
ltms = (struct LifeTimeMonitorData*)ILibMemory_SmartAllocate(sizeof(struct LifeTimeMonitorData));
|
ltms = (struct LifeTimeMonitorData*)ILibMemory_SmartAllocate(sizeof(struct LifeTimeMonitorData));
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|||||||
Reference in New Issue
Block a user