mirror of
https://github.com/Ylianst/MeshAgent
synced 2026-01-05 18:13:38 +00:00
Merge branch 'Branch_pathfix'
This commit is contained in:
@@ -110,38 +110,15 @@ void ILibDuktape_ChildProcess_SubProcess_ExitHandler(ILibProcessPipe_Process sen
|
||||
ILibDuktape_ChildProcess_SubProcess *p = (ILibDuktape_ChildProcess_SubProcess*)user;
|
||||
if (!ILibMemory_CanaryOK(p)) { return; }
|
||||
|
||||
#ifdef WIN32
|
||||
if (duk_ctx_context_data(p->ctx)->apc_flags == 0 && p->dispatchFlags == 0)
|
||||
{
|
||||
// This method was called with an APC, but this thread was running an unknown alertable method when it was interrupted
|
||||
// So we must unwind the stack, and use a non-apc method to re-dispatch to this thread, becuase we can't risk
|
||||
// calling a winsock method, in case this thread was inside winsock when it was interrupted, because otherwise, it
|
||||
// will corrupt memory, resulting in a possible crash.
|
||||
//
|
||||
// We had to do the APC first, becuase otherwise child_process.waitExit() will not work, becuase that method is blocking
|
||||
// the event loop thread with an alertable wait object, so APC is the only way to propagate this event
|
||||
p->exitCode = exitCode;
|
||||
p->dispatchFlags = 1;
|
||||
Duktape_RunOnEventLoop(p->chain, duk_ctx_nonce(p->ctx), p->ctx, ILibDuktape_ChildProcess_SubProcess_ExitHandler_sink1, NULL, p);
|
||||
}
|
||||
#endif
|
||||
|
||||
p->exitCode = exitCode;
|
||||
p->childProcess = NULL;
|
||||
duk_push_heapptr(p->ctx, p->subProcess); // [childProcess]
|
||||
|
||||
#ifdef WIN32
|
||||
HANDLE exitptr = (HANDLE)Duktape_GetPointerProperty(p->ctx, -1, "\xFF_WaitExit");
|
||||
if (exitptr != NULL)
|
||||
{
|
||||
SetEvent(exitptr);
|
||||
}
|
||||
#else
|
||||
if (Duktape_GetIntPropertyValue(p->ctx, -1, "\xFF_WaitExit", 0) != 0)
|
||||
{
|
||||
ILibChain_EndContinue(Duktape_GetChain(p->ctx));
|
||||
}
|
||||
#endif
|
||||
|
||||
duk_get_prop_string(p->ctx, -1, "emit"); // [childProcess][emit]
|
||||
duk_swap_top(p->ctx, -2); // [emit][this]
|
||||
duk_push_string(p->ctx, "exit"); // [emit][this][exit]
|
||||
@@ -185,6 +162,7 @@ duk_ret_t ILibDuktape_ChildProcess_Kill(duk_context *ctx)
|
||||
}
|
||||
duk_ret_t ILibDuktape_ChildProcess_waitExit(duk_context *ctx)
|
||||
{
|
||||
int timeout = duk_is_number(ctx, 0) ? duk_require_int(ctx, 0) : -1;
|
||||
void *chain = Duktape_GetChain(ctx);
|
||||
if (ILibIsChainBeingDestroyed(chain))
|
||||
{
|
||||
@@ -192,29 +170,23 @@ duk_ret_t ILibDuktape_ChildProcess_waitExit(duk_context *ctx)
|
||||
}
|
||||
|
||||
duk_push_this(ctx); // [spawnedProcess]
|
||||
char *_target = Duktape_GetStringPropertyValue(ctx, -1, "_target", NULL);
|
||||
if (!ILibChain_IsLinkAlive(Duktape_GetPointerProperty(ctx, -1, ILibDuktape_ChildProcess_Manager)))
|
||||
{
|
||||
return(ILibDuktape_Error(ctx, "Cannot waitExit() because JS Engine is exiting"));
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
DWORD result;
|
||||
HANDLE eptr = CreateEventA(NULL, TRUE, FALSE, NULL);
|
||||
duk_push_pointer(ctx, (void*)eptr);
|
||||
#else
|
||||
duk_push_int(ctx, 1); // [spawnedProcess][flag]
|
||||
#endif
|
||||
duk_put_prop_string(ctx, -2, "\xFF_WaitExit"); // [spawnedProcess]
|
||||
|
||||
#ifdef WIN32
|
||||
duk_ctx_context_data(ctx)->apc_flags = 1;
|
||||
while ((result=WaitForSingleObjectEx(eptr, duk_is_number(ctx, 0) ? duk_require_int(ctx, 0) : INFINITE, TRUE)) != WAIT_OBJECT_0 && result != WAIT_TIMEOUT);
|
||||
duk_ctx_context_data(ctx)->apc_flags = 0;
|
||||
CloseHandle(eptr);
|
||||
if (result == WAIT_TIMEOUT) { return(ILibDuktape_Error(ctx, "timeout")); }
|
||||
#else
|
||||
void *mods[] = { ILibGetBaseTimer(Duktape_GetChain(ctx)), Duktape_GetPointerProperty(ctx, -1, ILibDuktape_ChildProcess_Manager) };
|
||||
ILibChain_Continue(chain, (ILibChain_Link**)mods, 2, -1);
|
||||
#ifdef WIN32
|
||||
HANDLE handles[] = { NULL, NULL, NULL, NULL, NULL };
|
||||
ILibProcessPipe_Process p = Duktape_GetPointerProperty(ctx, -1, ILibDuktape_ChildProcess_Process);
|
||||
ILibProcessPipe_Process_GetWaitHandles(p, &(handles[0]), &(handles[1]), &(handles[2]), &(handles[3]));
|
||||
ILibChain_Continue(chain, (ILibChain_Link**)mods, 2, timeout, (HANDLE**)handles);
|
||||
#else
|
||||
ILibChain_Continue(chain, (ILibChain_Link**)mods, 2, timeout);
|
||||
#endif
|
||||
|
||||
return(0);
|
||||
@@ -432,6 +404,7 @@ duk_ret_t ILibDuktape_ChildProcess_execFile(duk_context *ctx)
|
||||
return(ILibDuktape_Error(ctx, "child_process.execFile(): Could not exec [%s]", target));
|
||||
}
|
||||
ILibDuktape_ChildProcess_SpawnedProcess_PUSH(ctx, p, callback);
|
||||
duk_push_string(ctx, target); duk_put_prop_string(ctx, -2, "_target");
|
||||
duk_push_pointer(ctx, manager); duk_put_prop_string(ctx, -2, ILibDuktape_ChildProcess_Manager);
|
||||
return(1);
|
||||
}
|
||||
|
||||
@@ -160,6 +160,8 @@ ILibTransport_DoneState ILibDuktape_HECI_Session_WriteHandler_Process(ILibDuktap
|
||||
extern int ILibDuktape_HECI_Debug;
|
||||
|
||||
#ifdef WIN32
|
||||
BOOL ILibDuktape_HECI_Session_ReceiveSink(void *chain, HANDLE event, ILibWaitHandle_ErrorStatus errors, void* user);
|
||||
|
||||
HANDLE ILibDuktape_HECI_windowsInit()
|
||||
{
|
||||
PSP_DEVICE_INTERFACE_DETAIL_DATA deviceDetail = NULL;
|
||||
@@ -284,7 +286,7 @@ void ILibDuktape_HECI_Session_EmitStreamReady(void *chain, void *session)
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
BOOL ILibDuktape_HECI_Session_WriteHandler_Ready(HANDLE event, ILibWaitHandle_ErrorStatus errors, void* user)
|
||||
BOOL ILibDuktape_HECI_Session_WriteHandler_Ready(void *chain, HANDLE event, ILibWaitHandle_ErrorStatus errors, void* user)
|
||||
{
|
||||
if (errors != ILibWaitHandle_ErrorStatus_NONE) { return(FALSE); }
|
||||
|
||||
@@ -293,8 +295,8 @@ BOOL ILibDuktape_HECI_Session_WriteHandler_Ready(HANDLE event, ILibWaitHandle_Er
|
||||
|
||||
if (!ILibMemory_CanaryOK(session)) { return(FALSE); }
|
||||
|
||||
ILibProcessPipe_WaitHandle_Remove(session->mgr, session->wv.hEvent);
|
||||
|
||||
ILibChain_RemoveWaitHandle(session->chain, session->wv.hEvent);
|
||||
|
||||
if (session->noPipelining == 0)
|
||||
{
|
||||
ILibDuktape_HECI_WriteState *state = (ILibDuktape_HECI_WriteState*)ILibQueue_DeQueue(session->PendingWrites);
|
||||
@@ -378,7 +380,7 @@ ILibTransport_DoneState ILibDuktape_HECI_Session_WriteHandler_Process(ILibDuktap
|
||||
{
|
||||
// Not done writing
|
||||
retVal = ILibTransport_DoneState_INCOMPLETE;
|
||||
ILibProcessPipe_WaitHandle_Add(session->mgr, session->wv.hEvent, session, ILibDuktape_HECI_Session_WriteHandler_Ready);
|
||||
ILibChain_AddWaitHandle(session->chain, session->wv.hEvent, -1, ILibDuktape_HECI_Session_WriteHandler_Ready, session);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -471,7 +473,7 @@ ILibTransport_DoneState ILibDuktape_HECI_Session_WriteSink(ILibDuktape_DuplexStr
|
||||
{
|
||||
#if defined(WIN32)
|
||||
state->returnIgnored = 1;
|
||||
QueueUserAPC((PAPCFUNC)ILibDuktape_HECI_Session_WriteHandler, ILibProcessPipe_Manager_GetWorkerThread(session->mgr), (ULONG_PTR)state);
|
||||
ILibDuktape_HECI_Session_WriteHandler((ULONG_PTR)state);
|
||||
#elif defined(_POSIX)
|
||||
if (ILibIsRunningOnChainThread(stream->readableStream->chain) != 0)
|
||||
{
|
||||
@@ -520,20 +522,6 @@ void ILibDuktape_HECI_Session_PauseSink(ILibDuktape_DuplexStream *sender, void *
|
||||
UNREFERENCED_PARAMETER(user);
|
||||
#endif
|
||||
}
|
||||
#ifdef WIN32
|
||||
BOOL ILibDuktape_HECI_Session_ReceiveSink(HANDLE event, ILibWaitHandle_ErrorStatus errors, void* user);
|
||||
void __stdcall ILibDuktape_HECI_Session_ResumeSink2(ULONG_PTR obj)
|
||||
{
|
||||
//if (ILibDuktape_HECI_Debug) { printf("ILibDuktape_HECI_Session_ResumeSink2()\n"); }
|
||||
ILibDuktape_HECI_Session *session = (ILibDuktape_HECI_Session*)obj;
|
||||
BOOL result = ReadFile(session->descriptor, session->buffer, (DWORD)session->bufferSize, &(session->bytesRead), &(session->v));
|
||||
if (result == TRUE || GetLastError() == ERROR_IO_PENDING)
|
||||
{
|
||||
//if (ILibDuktape_HECI_Debug) { printf("...[Wait Handle Added]\n"); }
|
||||
ILibProcessPipe_WaitHandle_Add(session->mgr, session->v.hEvent, session, ILibDuktape_HECI_Session_ReceiveSink);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
void ILibDuktape_HECI_Session_ResumeSink_NoPipeline(void *chain, void *user)
|
||||
{
|
||||
// This is always called from the Microstack Thread
|
||||
@@ -555,13 +543,16 @@ void ILibDuktape_HECI_Session_ResumeSink(ILibDuktape_DuplexStream *sender, void
|
||||
ILibDuktape_HECI_Session *session = (ILibDuktape_HECI_Session*)user;
|
||||
if (session->noPipelining != 0)
|
||||
{
|
||||
Duktape_RunOnEventLoop(sender->readableStream->chain, duk_ctx_nonce(sender->readableStream->ctx), sender->readableStream->ctx, ILibDuktape_HECI_Session_ResumeSink_NoPipeline, NULL, session);
|
||||
// Note: DO NOT 'return' here, because we still need to QueueUserAPC, to resume the stream on Windows
|
||||
ILibDuktape_HECI_Session_ResumeSink_NoPipeline(sender->readableStream->chain, session);
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
// To Resume, we need to first context switch to the Windows Thread
|
||||
QueueUserAPC((PAPCFUNC)ILibDuktape_HECI_Session_ResumeSink2, ILibProcessPipe_Manager_GetWorkerThread(session->mgr), (ULONG_PTR)session);
|
||||
BOOL result = ReadFile(session->descriptor, session->buffer, (DWORD)session->bufferSize, &(session->bytesRead), &(session->v));
|
||||
if (result == TRUE || GetLastError() == ERROR_IO_PENDING)
|
||||
{
|
||||
//if (ILibDuktape_HECI_Debug) { printf("...[Wait Handle Added]\n"); }
|
||||
ILibChain_AddWaitHandle(session->chain, session->v.hEvent, -1, ILibDuktape_HECI_Session_ReceiveSink, session);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#ifdef WIN32
|
||||
@@ -576,7 +567,7 @@ void ILibDuktape_HECI_Session_ReceiveSink2(void *chain, void *user)
|
||||
ILibDuktape_HECI_Session_ResumeSink(session->stream, session->stream->user);
|
||||
}
|
||||
}
|
||||
BOOL ILibDuktape_HECI_Session_ReceiveSink(HANDLE event, ILibWaitHandle_ErrorStatus errors, void* user)
|
||||
BOOL ILibDuktape_HECI_Session_ReceiveSink(void *chain, HANDLE event, ILibWaitHandle_ErrorStatus errors, void* user)
|
||||
{
|
||||
//if (ILibDuktape_HECI_Debug) { printf("ILibDuktape_HECI_Session_ReceiveSink\n"); }
|
||||
if (errors != ILibWaitHandle_ErrorStatus_NONE)
|
||||
@@ -589,7 +580,14 @@ BOOL ILibDuktape_HECI_Session_ReceiveSink(HANDLE event, ILibWaitHandle_ErrorStat
|
||||
ILibDuktape_HECI_Session *session = (ILibDuktape_HECI_Session*)user;
|
||||
if (ILibMemory_CanaryOK(session))
|
||||
{
|
||||
if (GetOverlappedResult(session->descriptor, &(session->v), &(session->bytesRead), FALSE) == TRUE) { Duktape_RunOnEventLoop(session->chain, duk_ctx_nonce(session->stream->readableStream->ctx), session->stream->readableStream->ctx, ILibDuktape_HECI_Session_ReceiveSink2, NULL, session); }
|
||||
if (GetOverlappedResult(session->descriptor, &(session->v), &(session->bytesRead), FALSE) == TRUE)
|
||||
{
|
||||
ILibDuktape_DuplexStream_WriteData(session->stream, session->buffer, session->bytesRead);
|
||||
if (session->stream != NULL && !session->stream->readableStream->paused)
|
||||
{
|
||||
ILibDuktape_HECI_Session_ResumeSink(session->stream, session->stream->user);
|
||||
}
|
||||
}
|
||||
}
|
||||
return(FALSE);
|
||||
}
|
||||
@@ -601,7 +599,7 @@ void __stdcall ILibDuktape_HECI_Session_Start(ULONG_PTR obj)
|
||||
BOOL result = ReadFile(session->descriptor, session->buffer, (DWORD)session->bufferSize, &bytesRead, &(session->v));
|
||||
//if (ILibDuktape_HECI_Debug) { printf("...[WaitHandle Added]\n"); }
|
||||
|
||||
ILibProcessPipe_WaitHandle_Add(session->mgr, session->v.hEvent, session, ILibDuktape_HECI_Session_ReceiveSink);
|
||||
ILibChain_AddWaitHandle(session->chain, session->v.hEvent, -1, ILibDuktape_HECI_Session_ReceiveSink, session);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -677,7 +675,7 @@ duk_ret_t ILibDuktape_HECI_create_OnClientConnect(duk_context *ctx)
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_HECI_ChildProcess); // [HECI][childProcess]
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_ChildProcess_Manager); // [HECI][childProcess][manager]
|
||||
session->mgr = (ILibProcessPipe_Manager)duk_get_pointer(ctx, -1);
|
||||
QueueUserAPC((PAPCFUNC)ILibDuktape_HECI_Session_Start, ILibProcessPipe_Manager_GetWorkerThread(session->mgr), (ULONG_PTR)session);
|
||||
ILibDuktape_HECI_Session_Start((ULONG_PTR)session);
|
||||
#else
|
||||
duk_push_this(ctx); // [HECI]
|
||||
session->descriptor = Duktape_GetIntPropertyValue(ctx, -1, ILibDuktape_HECI_Descriptor, -1);
|
||||
@@ -756,10 +754,10 @@ duk_ret_t ILibDuktape_HECI_Session_close(duk_context *ctx)
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_HECI_SessionMemPtr); // [HECI][SESSION]
|
||||
session = (ILibDuktape_HECI_Session*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
|
||||
ILibProcessPipe_WaitHandle_Remove(session->mgr, session->v.hEvent);
|
||||
ILibProcessPipe_WaitHandle_Remove(session->mgr, session->wv.hEvent);
|
||||
ILibChain_RemoveWaitHandle(session->chain, session->v.hEvent);
|
||||
ILibChain_RemoveWaitHandle(session->chain, session->wv.hEvent);
|
||||
session->stream = NULL;
|
||||
QueueUserAPC((PAPCFUNC)ILibDuktape_HECI_Session_CloseSink2, ILibProcessPipe_Manager_GetWorkerThread(session->mgr), (ULONG_PTR)session->descriptor);
|
||||
CloseHandle(session->descriptor);
|
||||
}
|
||||
#else
|
||||
int d = Duktape_GetIntPropertyValue(ctx, -1, ILibDuktape_HECI_Descriptor, -1);
|
||||
@@ -851,7 +849,7 @@ void ILibDuktape_HECI_IoctlHandler_Dispatch(void *chain, void *user)
|
||||
}
|
||||
#ifdef WIN32
|
||||
void ILibDuktape_HECI_NextIoctl(ILibQueue q);
|
||||
BOOL ILibDuktape_HECI_IoctlHandler(HANDLE h, ILibWaitHandle_ErrorStatus errors, void *user)
|
||||
BOOL ILibDuktape_HECI_IoctlHandler(void * chain, HANDLE h, ILibWaitHandle_ErrorStatus errors, void *user)
|
||||
{
|
||||
if (errors == ILibWaitHandle_ErrorStatus_INVALID_HANDLE || errors == ILibWaitHandle_ErrorStatus_REMOVED) { return(FALSE); }
|
||||
if (!ILibMemory_CanaryOK(user)) { return(FALSE); }
|
||||
@@ -870,7 +868,7 @@ BOOL ILibDuktape_HECI_IoctlHandler(HANDLE h, ILibWaitHandle_ErrorStatus errors,
|
||||
}
|
||||
|
||||
ILibQueue_DeQueue(data->Q);
|
||||
ILibProcessPipe_WaitHandle_Remove(data->pipeManager, h);
|
||||
ILibChain_RemoveWaitHandle(data->chain, h);
|
||||
|
||||
if (data->abort != 0 || !ILibMemory_CanaryOK(data->reserved))
|
||||
{
|
||||
@@ -888,7 +886,7 @@ BOOL ILibDuktape_HECI_IoctlHandler(HANDLE h, ILibWaitHandle_ErrorStatus errors,
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
Duktape_RunOnEventLoop(data->chain, data->ctxnonce, data->ctx, ILibDuktape_HECI_IoctlHandler_Dispatch, NULL, data);
|
||||
ILibDuktape_HECI_IoctlHandler_Dispatch(data->chain, data);
|
||||
|
||||
if (ILibQueue_GetCount(Q) > 0)
|
||||
{
|
||||
@@ -906,8 +904,7 @@ void ILibDuktape_HECI_NextIoctl(ILibQueue q)
|
||||
|
||||
ResetEvent(data->v.hEvent);
|
||||
res = DeviceIoControl(data->device, (DWORD)data->code, data->buffer, (DWORD)data->bufferLen, data->outBuffer, (DWORD)data->outBufferLen, &(data->bytesReceived), &(data->v));
|
||||
ILibProcessPipe_WaitHandle_Add_WithNonZeroTimeout(data->pipeManager, data->v.hEvent, 2000, data, ILibDuktape_HECI_IoctlHandler);
|
||||
|
||||
ILibChain_AddWaitHandle(data->chain, data->v.hEvent, 2000, ILibDuktape_HECI_IoctlHandler, data);
|
||||
}
|
||||
void __stdcall ILibDuktape_HECI_apc_AddIoctl(ULONG_PTR obj)
|
||||
{
|
||||
@@ -1031,7 +1028,8 @@ duk_ret_t ILibDuktape_HECI_doIoctl(duk_context *ctx)
|
||||
duk_get_prop_string(ctx, -2, ILibDuktape_HECI_ChildProcess); // [heci][stash][childProcess]
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_ChildProcess_Manager); // [heci][stash][childProcess][manager]
|
||||
data->pipeManager = (ILibProcessPipe_Manager)duk_get_pointer(ctx, -1);
|
||||
QueueUserAPC((PAPCFUNC)ILibDuktape_HECI_apc_AddIoctl, ILibProcessPipe_Manager_GetWorkerThread(data->pipeManager), (ULONG_PTR)data);
|
||||
|
||||
ILibDuktape_HECI_apc_AddIoctl((ULONG_PTR)data);
|
||||
#elif defined(_POSIX)
|
||||
ILibDuktape_HECI_AddIoctl(data);
|
||||
#endif
|
||||
@@ -1074,8 +1072,8 @@ duk_ret_t ILibDuktape_HECI_Finalizer(duk_context *ctx)
|
||||
#ifdef WIN32
|
||||
ILibQueue Q = (ILibQueue)Duktape_GetPointerProperty(ctx, 0, ILibDuktape_HECI_Q);
|
||||
duk_get_prop_string(ctx, 0, ILibDuktape_HECI_ChildProcess);
|
||||
ILibProcessPipe_Manager mgr = (ILibProcessPipe_Manager)Duktape_GetPointerProperty(ctx, -1, ILibDuktape_ChildProcess_Manager);
|
||||
if (mgr != NULL) { QueueUserAPC((PAPCFUNC)ILibDuktape_HECI_Finalizer2, ILibProcessPipe_Manager_GetWorkerThread(mgr), (ULONG_PTR)Q); }
|
||||
ILibProcessPipe_Manager mgr = (ILibProcessPipe_Manager)Duktape_GetPointerProperty(ctx, -1, ILibDuktape_ChildProcess_Manager);
|
||||
ILibDuktape_HECI_Finalizer2((ULONG_PTR)Q);
|
||||
#else
|
||||
duk_get_prop_string(ctx, 0, ILibDuktape_HECI_Q);
|
||||
ILibQueue_Destroy((ILibQueue)duk_get_pointer(ctx, -1));
|
||||
|
||||
@@ -93,6 +93,9 @@ void *Duktape_Duplicate_GetBufferPropertyEx(duk_context *ctx, duk_idx_t i, char*
|
||||
char *Duktape_Duplicate_GetStringEx(duk_context *ctx, duk_idx_t i, duk_size_t *len);
|
||||
#define Duktape_Duplicate_GetString(ctx, i) Duktape_Duplicate_GetStringEx(ctx, i, NULL)
|
||||
|
||||
#define duk_array_shift(ctx, i) duk_dup(ctx, i);duk_get_prop_string(ctx, -1, "shift");duk_swap_top(ctx, -2);duk_call_method(ctx, 0);
|
||||
#define duk_array_pop(ctx, i) duk_dup(ctx, i);duk_get_prop_string(ctx, -1, "pop");duk_swap_top(ctx, -2);duk_call_method(ctx, 0);
|
||||
|
||||
int Duktape_GetBooleanProperty(duk_context *ctx, duk_idx_t i, char *propertyName, int defaultValue);
|
||||
struct sockaddr_in6* Duktape_IPAddress4_FromString(char* address, unsigned short port);
|
||||
struct sockaddr_in6* Duktape_IPAddress6_FromString(char* address, unsigned short port);
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -260,7 +260,7 @@ void ILibDuktape_ScriptContainer_GetEmbeddedJS_Raw(char *exePath, char **script,
|
||||
int integratedJavaScriptLen = 0;
|
||||
FILE* tmpFile = NULL;
|
||||
|
||||
fopen_s(&tmpFile, exePath, "rb");
|
||||
_wfopen_s(&tmpFile, ILibUTF8ToWide(exePath, -1), L"rb");
|
||||
if (tmpFile != NULL)
|
||||
{
|
||||
// Read the PE Headers, to determine where to look for the Embedded JS
|
||||
@@ -338,7 +338,7 @@ void ILibDuktape_ScriptContainer_CheckEmbeddedEx(char *exePath, char **script, i
|
||||
{
|
||||
i = sprintf_s(g_AgentCrashID, sizeof(g_AgentCrashID), "%s_", exePath);
|
||||
sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "%s.exe", exePath);
|
||||
fopen_s(&tmpFile, ILibScratchPad, "rb");
|
||||
_wfopen_s(&tmpFile, ILibUTF8ToWide(ILibScratchPad, -1), L"rb");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -373,7 +373,7 @@ void ILibDuktape_ScriptContainer_CheckEmbeddedEx(char *exePath, char **script, i
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
fopen_s(&tmpFile, exePath, "rb");
|
||||
_wfopen_s(&tmpFile, ILibUTF8ToWide(exePath, -1), L"rb");
|
||||
#else
|
||||
tmpFile = fopen(exePath, "rb");
|
||||
#endif
|
||||
@@ -465,13 +465,15 @@ void ILibDuktape_ScriptContainer_CheckEmbedded(char **script, int *scriptLen)
|
||||
// Check if .JS file is integrated with executable
|
||||
|
||||
#ifndef __APPLE__
|
||||
char exePath[_MAX_PATH];
|
||||
char exePath[_MAX_PATH*2];
|
||||
#else
|
||||
char exePath[PATH_MAX+1];
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
GetModuleFileName(NULL, exePath, sizeof(exePath));
|
||||
WCHAR tmpExePath[_MAX_PATH];
|
||||
GetModuleFileNameW(NULL, tmpExePath, sizeof(tmpExePath)/2);
|
||||
WideCharToMultiByte(CP_UTF8, 0, tmpExePath, -1, exePath, sizeof(exePath), NULL, NULL);
|
||||
#elif defined(__APPLE__)
|
||||
uint32_t len = sizeof(exePath);
|
||||
if (_NSGetExecutablePath(exePath, &len) != 0) ILIBCRITICALEXIT(247);
|
||||
@@ -500,6 +502,18 @@ void ILibDuktape_ScriptContainer_Process_ExitCallback(void *obj)
|
||||
Duktape_SafeDestroyHeap(ctx);
|
||||
}
|
||||
}
|
||||
duk_ret_t ILibDuktape_ScriptContainer_Process_ExitEx(duk_context *ctx)
|
||||
{
|
||||
if (duk_is_number(ctx, 0))
|
||||
{
|
||||
exit(duk_require_int(ctx, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
exit(0);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_ScriptContainer_Process_Exit(duk_context *ctx)
|
||||
{
|
||||
void **tmp;
|
||||
@@ -861,16 +875,23 @@ duk_ret_t ILibDuktape_ScriptContainer_Process_Kill(duk_context *ctx)
|
||||
duk_ret_t ILibDuktape_Process_cwd(duk_context *ctx)
|
||||
{
|
||||
#ifdef WIN32
|
||||
GetCurrentDirectoryA((DWORD)sizeof(ILibScratchPad), ILibScratchPad);
|
||||
duk_push_string(ctx, ILibScratchPad);
|
||||
return(1);
|
||||
#elif defined(_POSIX)
|
||||
GetCurrentDirectoryW((DWORD)sizeof(ILibScratchPad)/2, (LPWSTR)ILibScratchPad);
|
||||
ILibDuktape_String_PushWideString(ctx, ILibScratchPad, 0);
|
||||
#else
|
||||
ignore_result((uintptr_t)getcwd(ILibScratchPad, sizeof(ILibScratchPad)));
|
||||
duk_push_string(ctx, ILibScratchPad);
|
||||
return(1);
|
||||
#else
|
||||
return(ILibDuktape_Error(ctx, "Error"));
|
||||
#endif
|
||||
|
||||
duk_get_prop_string(ctx, -1, "concat"); // [string][concat]
|
||||
duk_swap_top(ctx, -2); // [concat][this]
|
||||
#ifdef WIN32
|
||||
duk_push_string(ctx, "\\");
|
||||
#else
|
||||
duk_push_string(ctx, "/");
|
||||
#endif
|
||||
|
||||
duk_call_method(ctx, 1);
|
||||
return(1);
|
||||
}
|
||||
|
||||
#ifdef _POSIX
|
||||
@@ -1236,6 +1257,7 @@ void ILibDuktape_ScriptContainer_Process_Init(duk_context *ctx, char **argList)
|
||||
emitter = ILibDuktape_EventEmitter_Create(ctx);
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "exit");
|
||||
ILibDuktape_CreateProperty_InstanceMethod(ctx, "exit", ILibDuktape_ScriptContainer_Process_Exit, DUK_VARARGS);
|
||||
ILibDuktape_CreateProperty_InstanceMethod(ctx, "_exit", ILibDuktape_ScriptContainer_Process_ExitEx, DUK_VARARGS);
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "uncaughtException");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "SIGTERM");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "SIGCHLD");
|
||||
@@ -1577,9 +1599,7 @@ duk_ret_t ILibDuktape_ScriptContainer_OS_networkInterfaces(duk_context *ctx)
|
||||
ILibDuktape_CreateReadonlyProperty(ctx, "interfaceIndexes");
|
||||
|
||||
char fqdn[4096];
|
||||
size_t fqdnLen;
|
||||
int i = 0;
|
||||
size_t converted;
|
||||
char tmpBuffer[32768];
|
||||
DWORD tmpBufferSize = sizeof(tmpBuffer);
|
||||
IP_ADAPTER_ADDRESSES *padapters = (IP_ADAPTER_ADDRESSES*)tmpBuffer;
|
||||
@@ -1603,7 +1623,7 @@ duk_ret_t ILibDuktape_ScriptContainer_OS_networkInterfaces(duk_context *ctx)
|
||||
duk_put_prop_string(ctx, -2, "gateway");
|
||||
}
|
||||
|
||||
wcstombs_s(&fqdnLen, fqdn, sizeof(fqdn), (const wchar_t*)padapters->DnsSuffix, wcsnlen_s(padapters->DnsSuffix, sizeof(fqdn)));
|
||||
ILibWideToUTF8Ex((wchar_t*)padapters->DnsSuffix, -1, fqdn, (int)sizeof(fqdn));
|
||||
duk_push_string(ctx, fqdn);
|
||||
duk_put_prop_string(ctx, -2, "fqdn");
|
||||
|
||||
@@ -1654,7 +1674,7 @@ duk_ret_t ILibDuktape_ScriptContainer_OS_networkInterfaces(duk_context *ctx)
|
||||
duk_put_prop_index(ctx, -2, i++);
|
||||
addr = addr->Next;
|
||||
}
|
||||
wcstombs_s(&converted, ILibScratchPad, sizeof(ILibScratchPad), padapters->FriendlyName, sizeof(ILibScratchPad));
|
||||
ILibWideToUTF8Ex(padapters->FriendlyName, -1, ILibScratchPad, (int)sizeof(ILibScratchPad));
|
||||
duk_put_prop_string(ctx, -2, ILibScratchPad);
|
||||
|
||||
duk_push_heapptr(ctx, indexTable); // [table]
|
||||
@@ -1815,6 +1835,22 @@ duk_ret_t ILibDuktape_ScriptContainer_OS_hostname(duk_context *ctx)
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
duk_ret_t ILibDuktape_tmpdir(duk_context *ctx)
|
||||
{
|
||||
#ifdef WIN32
|
||||
WCHAR tmp[1024];
|
||||
if (GetTempPathW(sizeof(tmp) / 2, (LPWSTR)tmp) == 0) { return(ILibDuktape_Error(ctx, "Error getting temp folder")); }
|
||||
ILibDuktape_String_PushWideString(ctx, (char*)tmp, 0);
|
||||
#elif defined (_POSIX)
|
||||
#if defined(__APPLE__)
|
||||
duk_eval_string(ctx, "process.env['TMPDIR']");
|
||||
if (duk_is_undefined(ctx, -1)) { duk_push_string(ctx, "/private/tmp/"); }
|
||||
#else
|
||||
duk_push_string(ctx, "/var/tmp/");
|
||||
#endif
|
||||
#endif
|
||||
return(1);
|
||||
}
|
||||
void ILibDuktape_ScriptContainer_OS_Push(duk_context *ctx, void *chain)
|
||||
{
|
||||
duk_push_object(ctx); // [os]
|
||||
@@ -1834,6 +1870,7 @@ void ILibDuktape_ScriptContainer_OS_Push(duk_context *ctx, void *chain)
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "networkInterfaces", ILibDuktape_ScriptContainer_OS_networkInterfaces, 0);
|
||||
#endif
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "hostname", ILibDuktape_ScriptContainer_OS_hostname, 0);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "tmpdir", ILibDuktape_tmpdir, 0);
|
||||
|
||||
char jsExtras[] = "exports.getPrimaryDnsSuffix = function getPrimaryDnsSuffix()\
|
||||
{\
|
||||
@@ -2161,34 +2198,31 @@ void ILibDuktape_ScriptContainer_OS_Push(duk_context *ctx, void *chain)
|
||||
exports.Name = (function Name()\
|
||||
{\
|
||||
var child;\
|
||||
switch (process.platform)\
|
||||
if(process.platform!='win32')\
|
||||
{\
|
||||
case 'freebsd':\
|
||||
case 'linux':\
|
||||
case 'darwin':\
|
||||
child = require('child_process').execFile('/bin/sh', ['sh']);\
|
||||
break;\
|
||||
case 'win32':\
|
||||
child = require('child_process').execFile('%windir%\\\\system32\\\\cmd.exe');\
|
||||
break;\
|
||||
switch (process.platform)\
|
||||
{\
|
||||
case 'freebsd':\
|
||||
case 'linux':\
|
||||
case 'darwin':\
|
||||
child = require('child_process').execFile('/bin/sh', ['sh']);\
|
||||
break;\
|
||||
}\
|
||||
child.stdout.str=''; child.stdout.on('data', function(chunk) { this.str += chunk.toString(); });\
|
||||
switch (process.platform)\
|
||||
{\
|
||||
case 'linux':\
|
||||
child.stdin.write('cat /etc/*release\\nexit\\n');\
|
||||
break;\
|
||||
case 'darwin':\
|
||||
child.stdin.write('sw_vers\\nexit\\n');\
|
||||
break;\
|
||||
case 'freebsd':\
|
||||
child.stdin.write('uname -mrs\\nexit\\n');\
|
||||
break;\
|
||||
}\
|
||||
child.waitExit();\
|
||||
}\
|
||||
child.stdout.str=''; child.stdout.on('data', function(chunk) { this.str += chunk.toString(); });\
|
||||
switch (process.platform)\
|
||||
{\
|
||||
case 'linux':\
|
||||
child.stdin.write('cat /etc/*release\\nexit\\n');\
|
||||
break;\
|
||||
case 'darwin':\
|
||||
child.stdin.write('sw_vers\\nexit\\n');\
|
||||
break;\
|
||||
case 'win32':\
|
||||
child.stdin.write('exit\\r\\n');\
|
||||
break;\
|
||||
case 'freebsd':\
|
||||
child.stdin.write('uname -mrs\\nexit\\n');\
|
||||
break;\
|
||||
}\
|
||||
child.waitExit();\
|
||||
var ret=null;\
|
||||
var lines;\
|
||||
var tokens;\
|
||||
@@ -2196,17 +2230,15 @@ void ILibDuktape_ScriptContainer_OS_Push(duk_context *ctx, void *chain)
|
||||
switch (process.platform)\
|
||||
{\
|
||||
case 'win32':\
|
||||
var winstr = child.stdout.str.split('\\r\\n')[0];\
|
||||
if(require('user-sessions').isRoot())\
|
||||
{\
|
||||
try\
|
||||
{\
|
||||
winstr = require('win-registry').QueryKey(require('win-registry').HKEY.LocalMachine, 'SOFTWARE\\\\Microsoft\\\\Windows NT\\\\CurrentVersion', 'ProductName') + ' - ' +\
|
||||
require('win-registry').QueryKey(require('win-registry').HKEY.LocalMachine, 'SOFTWARE\\\\Microsoft\\\\Windows NT\\\\CurrentVersion', 'ReleaseID') + ' ' + winstr.substring(winstr.indexOf('['));\
|
||||
require('win-registry').QueryKey(require('win-registry').HKEY.LocalMachine, 'SOFTWARE\\\\Microsoft\\\\Windows NT\\\\CurrentVersion', 'ReleaseID');\
|
||||
}\
|
||||
catch(xx)\
|
||||
{\
|
||||
winstr = require('win-registry').QueryKey(require('win-registry').HKEY.LocalMachine, 'SOFTWARE\\\\Microsoft\\\\Windows NT\\\\CurrentVersion', 'ProductName') + ' ' + winstr.substring(winstr.indexOf('['));\
|
||||
winstr = require('win-registry').QueryKey(require('win-registry').HKEY.LocalMachine, 'SOFTWARE\\\\Microsoft\\\\Windows NT\\\\CurrentVersion', 'ProductName');\
|
||||
}\
|
||||
}\
|
||||
ret = winstr;\
|
||||
@@ -2255,97 +2287,7 @@ void ILibDuktape_ScriptContainer_OS_Push(duk_context *ctx, void *chain)
|
||||
{\
|
||||
var promise = require('promise');\
|
||||
var p = new promise(function(acc, rej) { this._acc = acc; this._rej = rej; });\
|
||||
switch (process.platform)\
|
||||
{\
|
||||
case 'freebsd':\
|
||||
case 'linux':\
|
||||
case 'darwin':\
|
||||
p.child = require('child_process').execFile('/bin/sh', ['sh']);\
|
||||
break;\
|
||||
case 'win32':\
|
||||
p.child = require('child_process').execFile('%windir%\\\\system32\\\\cmd.exe');\
|
||||
break;\
|
||||
}\
|
||||
p.child.promise = p;\
|
||||
p.child.stdout.str = '';\
|
||||
p.child.stdout.on('data', function(chunk) { this.str += chunk.toString(); });\
|
||||
p.child.on('exit', function(code)\
|
||||
{\
|
||||
var lines;\
|
||||
var tokens;\
|
||||
var i, j;\
|
||||
switch (process.platform)\
|
||||
{\
|
||||
case 'win32':\
|
||||
var winstr = this.stdout.str.split('\\r\\n')[0];\
|
||||
if(require('user-sessions').isRoot())\
|
||||
{\
|
||||
try\
|
||||
{\
|
||||
winstr = require('win-registry').QueryKey(require('win-registry').HKEY.LocalMachine, 'SOFTWARE\\\\Microsoft\\\\Windows NT\\\\CurrentVersion', 'ProductName') + ' - ' +\
|
||||
require('win-registry').QueryKey(require('win-registry').HKEY.LocalMachine, 'SOFTWARE\\\\Microsoft\\\\Windows NT\\\\CurrentVersion', 'ReleaseID') + ' ' + winstr.substring(winstr.indexOf('['));\
|
||||
}\
|
||||
catch(xx)\
|
||||
{\
|
||||
winstr = require('win-registry').QueryKey(require('win-registry').HKEY.LocalMachine, 'SOFTWARE\\\\Microsoft\\\\Windows NT\\\\CurrentVersion', 'ProductName') + ' ' + winstr.substring(winstr.indexOf('['));\
|
||||
}\
|
||||
}\
|
||||
this.promise._acc(winstr);\
|
||||
break;\
|
||||
case 'linux':\
|
||||
lines = this.stdout.str.split('\\n');\
|
||||
for (i in lines)\
|
||||
{\
|
||||
tokens = lines[i].split('=');\
|
||||
if (tokens[0] == 'PRETTY_NAME')\
|
||||
{\
|
||||
this.promise._acc(tokens[1].substring(1, tokens[1].length - 1));\
|
||||
break;\
|
||||
}\
|
||||
}\
|
||||
for (i in lines)\
|
||||
{\
|
||||
tokens = lines[i].split('=');\
|
||||
if (tokens[0] == 'DISTRIB_DESCRIPTION')\
|
||||
{\
|
||||
this.promise._acc(tokens[1].substring(1, tokens[1].length - 1));\
|
||||
break;\
|
||||
}\
|
||||
}\
|
||||
this.promise._acc(lines[0]);\
|
||||
break;\
|
||||
case 'darwin':\
|
||||
var OSNAME = '';\
|
||||
var OSVERSION = '';\
|
||||
lines = this.stdout.str.split('\\n');\
|
||||
for (i in lines)\
|
||||
{\
|
||||
tokens = lines[i].split(':');\
|
||||
if (tokens[0] == 'ProductName') { OSNAME = tokens[1].trim(); }\
|
||||
if (tokens[0] == 'ProductVersion') { OSVERSION = tokens[1].trim(); }\
|
||||
}\
|
||||
this.promise._acc(OSNAME + ' ' + OSVERSION);\
|
||||
break;\
|
||||
case 'freebsd':\
|
||||
this.promise._acc(this.stdout.str.trim());\
|
||||
break;\
|
||||
}\
|
||||
});\
|
||||
switch (process.platform)\
|
||||
{\
|
||||
case 'linux':\
|
||||
p.child.stdin.write('cat /etc/*release\\nexit\\n');\
|
||||
break;\
|
||||
case 'darwin':\
|
||||
p.child.stdin.write('sw_vers\\nexit\\n');\
|
||||
break;\
|
||||
case 'win32':\
|
||||
p.child.stdin.write('exit\\r\\n');\
|
||||
break;\
|
||||
case 'freebsd':\
|
||||
p.child.stdin.write('uname -mrs\\nexit\\n');\
|
||||
break;\
|
||||
}\
|
||||
p._acc(this.Name);\
|
||||
return (p);\
|
||||
};\
|
||||
if(process.platform=='freebsd')\
|
||||
@@ -3144,6 +3086,7 @@ void ILibDuktape_ScriptContainer_StdErrSink_MicrostackThread(void *chain, void *
|
||||
int bufferLen = ((int*)buffer)[0];
|
||||
void *ptr;
|
||||
int i;
|
||||
duk_context *ctx = master->ctx;
|
||||
|
||||
if (ILibDuktape_ScriptContainer_DecodeJSON(master->ctx, buffer+4, bufferLen-4) == 0)
|
||||
{
|
||||
@@ -3160,7 +3103,7 @@ void ILibDuktape_ScriptContainer_StdErrSink_MicrostackThread(void *chain, void *
|
||||
duk_push_string(master->ctx, json); // [emit][this][data][str]
|
||||
duk_json_decode(master->ctx, -1); // [emit][this][data][json]
|
||||
if (duk_pcall_method(master->ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(master->ctx, "ScriptContainer.OnData(): "); }
|
||||
duk_pop(master->ctx);
|
||||
duk_pop(ctx);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -3181,7 +3124,7 @@ void ILibDuktape_ScriptContainer_StdErrSink_MicrostackThread(void *chain, void *
|
||||
ILibDuktape_EventEmitter_SetupEmit(master->ctx, master->emitter->object, "error"); // [emit][this][error]
|
||||
duk_get_prop_string(master->ctx, -4, "error"); // [emit][this][error][errorObj]
|
||||
if (duk_pcall_method(master->ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(master->ctx, "ScriptContainer_OnError_Dispatch(): "); }
|
||||
duk_pop(master->ctx); // ...
|
||||
duk_pop(ctx); // ...
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3193,7 +3136,7 @@ void ILibDuktape_ScriptContainer_StdErrSink_MicrostackThread(void *chain, void *
|
||||
duk_push_false(master->ctx); // [func][this][false]
|
||||
duk_get_prop_string(master->ctx, -4, "error"); // [func][this][false][error]
|
||||
if (duk_pcall_method(master->ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(master->ctx, "ScriptContainer_OnError_Dispatch(): "); }
|
||||
duk_pop(master->ctx); // ...
|
||||
duk_pop(ctx); // ...
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3215,7 +3158,7 @@ void ILibDuktape_ScriptContainer_StdErrSink_MicrostackThread(void *chain, void *
|
||||
duk_push_undefined(master->ctx); // [func][this][true][undefined]
|
||||
}
|
||||
if (duk_pcall_method(master->ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(master->ctx, "ScriptContainer_OnExec_Dispatch(): "); }
|
||||
duk_pop(master->ctx); // ...
|
||||
duk_pop(ctx); // ...
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -3223,11 +3166,14 @@ void ILibDuktape_ScriptContainer_StdErrSink_MicrostackThread(void *chain, void *
|
||||
default:
|
||||
break;
|
||||
}
|
||||
duk_pop(master->ctx); // ...
|
||||
duk_pop(ctx); // ...
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
if (master->child != NULL) { ILibProcessPipe_Pipe_Resume(ILibProcessPipe_Process_GetStdErr(master->child)); }
|
||||
if (ILibMemory_CanaryOK(master))
|
||||
{
|
||||
if (master->child != NULL) { ILibProcessPipe_Pipe_Resume(ILibProcessPipe_Process_GetStdErr(master->child)); }
|
||||
}
|
||||
#endif
|
||||
}
|
||||
void ILibDuktape_ScriptContainer_StdErrSink(ILibProcessPipe_Process sender, char *buffer, int bufferLen, int* bytesConsumed, void* user)
|
||||
@@ -3243,6 +3189,7 @@ void ILibDuktape_ScriptContainer_StdErrSink(ILibProcessPipe_Process sender, char
|
||||
void **ptr = (void**)ILibMemory_Extra(ILibProcessPipe_Process_GetStdErr(sender));
|
||||
ptr[0] = master;
|
||||
ptr[1] = buffer;
|
||||
|
||||
ILibProcessPipe_Pipe_Pause(ILibProcessPipe_Process_GetStdErr(sender));
|
||||
Duktape_RunOnEventLoop(master->chain, duk_ctx_nonce(master->ctx), master->ctx, ILibDuktape_ScriptContainer_StdErrSink_MicrostackThread, NULL, ptr);
|
||||
}
|
||||
|
||||
@@ -922,7 +922,7 @@ duk_ret_t ILibDuktape_fs_watcher_close(duk_context *ctx)
|
||||
|
||||
#if defined(WIN32)
|
||||
int r = CancelIo(data->h);
|
||||
ILibProcessPipe_WaitHandle_Remove(data->pipeManager, data->overlapped.hEvent);
|
||||
ILibChain_RemoveWaitHandle(data->chain, data->overlapped.hEvent);
|
||||
CloseHandle(data->h);
|
||||
data->h = NULL;
|
||||
#elif defined(_POSIX) && !defined(__APPLE__) && !defined(_FREEBSD)
|
||||
@@ -959,52 +959,50 @@ duk_ret_t ILibDuktape_fs_watcher_close(duk_context *ctx)
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
BOOL ILibDuktape_fs_watch_iocompletion(HANDLE h, ILibWaitHandle_ErrorStatus errors, void *user);
|
||||
void ILibDuktape_fs_watch_iocompletionEx(void *chain, void *user)
|
||||
BOOL ILibDuktape_fs_watch_iocompletion(void *chain, HANDLE h, ILibWaitHandle_ErrorStatus errors, void *user)
|
||||
{
|
||||
if (errors != ILibWaitHandle_ErrorStatus_NONE || !ILibMemory_CanaryOK(user)) { return(FALSE); }
|
||||
ILibDuktape_fs_watcherData *data = (ILibDuktape_fs_watcherData*)user;
|
||||
FILE_NOTIFY_INFORMATION *n = (FILE_NOTIFY_INFORMATION*)data->results;
|
||||
char filename[4096];
|
||||
size_t filenameLen;
|
||||
|
||||
int changed = 0, renamed = 0;
|
||||
|
||||
BOOL ret = FALSE;
|
||||
|
||||
duk_push_object(data->ctx); // [detail]
|
||||
|
||||
while (n != NULL)
|
||||
{
|
||||
wcstombs_s(&filenameLen, filename, sizeof(filename), n->FileName, n->FileNameLength);
|
||||
ILibWideToUTF8_stupidEx(n->FileName, n->FileNameLength, filename, (int)sizeof(filename));
|
||||
switch (n->Action)
|
||||
{
|
||||
case FILE_ACTION_RENAMED_OLD_NAME:
|
||||
duk_push_lstring(data->ctx, filename, filenameLen-1);
|
||||
duk_push_string(data->ctx, filename);
|
||||
duk_put_prop_string(data->ctx, -2, "oldname");
|
||||
renamed = 1;
|
||||
break;
|
||||
case FILE_ACTION_RENAMED_NEW_NAME:
|
||||
duk_push_lstring(data->ctx, filename, filenameLen - 1);
|
||||
duk_push_string(data->ctx, filename);
|
||||
duk_put_prop_string(data->ctx, -2, "newname");
|
||||
renamed = 1;
|
||||
break;
|
||||
case FILE_ACTION_ADDED:
|
||||
duk_push_string(data->ctx, "ADDED");
|
||||
duk_put_prop_string(data->ctx, -2, "changeType");
|
||||
duk_push_lstring(data->ctx, filename, filenameLen - 1);
|
||||
duk_push_string(data->ctx, filename);
|
||||
duk_put_prop_string(data->ctx, -2, "\xFF_FileName");
|
||||
changed = 1;
|
||||
break;
|
||||
case FILE_ACTION_REMOVED:
|
||||
duk_push_string(data->ctx, "REMOVED");
|
||||
duk_put_prop_string(data->ctx, -2, "changeType");
|
||||
duk_push_lstring(data->ctx, filename, filenameLen - 1);
|
||||
duk_push_string(data->ctx, filename);
|
||||
duk_put_prop_string(data->ctx, -2, "\xFF_FileName");
|
||||
changed = 1;
|
||||
break;
|
||||
case FILE_ACTION_MODIFIED:
|
||||
duk_push_string(data->ctx, "MODIFIED");
|
||||
duk_put_prop_string(data->ctx, -2, "changeType");
|
||||
duk_push_lstring(data->ctx, filename, filenameLen - 1);
|
||||
duk_push_string(data->ctx, filename);
|
||||
duk_put_prop_string(data->ctx, -2, "\xFF_FileName");
|
||||
changed = 1;
|
||||
break;
|
||||
@@ -1041,18 +1039,10 @@ void ILibDuktape_fs_watch_iocompletionEx(void *chain, void *user)
|
||||
}
|
||||
else
|
||||
{
|
||||
ILibProcessPipe_WaitHandle_Add(data->pipeManager, data->overlapped.hEvent, data, ILibDuktape_fs_watch_iocompletion);
|
||||
ret = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
BOOL ILibDuktape_fs_watch_iocompletion(HANDLE h, ILibWaitHandle_ErrorStatus errors, void *user)
|
||||
{
|
||||
if (errors != ILibWaitHandle_ErrorStatus_NONE || !ILibMemory_CanaryOK(user)) { return(FALSE); }
|
||||
ILibDuktape_fs_watcherData *data = (ILibDuktape_fs_watcherData*)user;
|
||||
|
||||
ILibProcessPipe_WaitHandle_Remove(data->pipeManager, h);
|
||||
Duktape_RunOnEventLoop(data->chain, duk_ctx_nonce(data->ctx), data->ctx, ILibDuktape_fs_watch_iocompletionEx, NULL, data);
|
||||
return(TRUE);
|
||||
return(ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1287,7 +1277,7 @@ void ILibduktape_fs_watch_appleWorker(void *obj)
|
||||
duk_ret_t ILibDuktape_fs_watch(duk_context *ctx)
|
||||
{
|
||||
#ifdef WIN32
|
||||
char *path = (char*)duk_require_string(ctx, 0);
|
||||
WCHAR *path = (WCHAR*)ILibDuktape_String_AsWide(ctx, 0, NULL);
|
||||
#else
|
||||
char *path = ILibDuktape_fs_fixLinuxPath((char*)duk_require_string(ctx, 0));
|
||||
#endif
|
||||
@@ -1408,14 +1398,14 @@ duk_ret_t ILibDuktape_fs_watch(duk_context *ctx)
|
||||
|
||||
#if defined(WIN32)
|
||||
if ((data->overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL)) == NULL) { return(ILibDuktape_Error(ctx, "Could not create handle")); }
|
||||
data->h = CreateFile(path, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, NULL);
|
||||
data->h = CreateFileW(path, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, NULL);
|
||||
if (data->h == INVALID_HANDLE_VALUE) { return(ILibDuktape_Error(ctx, "fs.watch(): Invalid Path or Access Denied")); }
|
||||
|
||||
if (ReadDirectoryChangesW(data->h, data->results, sizeof(data->results), recursive, FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_CREATION | FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_LAST_ACCESS, NULL, &(data->overlapped), NULL) == 0)
|
||||
{
|
||||
return(ILibDuktape_Error(ctx, "fs.watch(): Error creating watcher"));
|
||||
}
|
||||
ILibProcessPipe_WaitHandle_Add(pipeMgr, data->overlapped.hEvent, data, ILibDuktape_fs_watch_iocompletion);
|
||||
ILibChain_AddWaitHandle(data->chain, data->overlapped.hEvent, -1, ILibDuktape_fs_watch_iocompletion, data);
|
||||
#elif defined(_POSIX) && !defined(__APPLE__) && !defined(_FREEBSD)
|
||||
data->wd.i = inotify_add_watch(data->linuxWatcher->fd, path, IN_CREATE | IN_DELETE | IN_MODIFY | IN_MOVED_FROM | IN_MOVED_TO);
|
||||
if (data->wd.i < 0)
|
||||
|
||||
@@ -82,18 +82,21 @@ int ILibDuktape_TLS_ctx2server = -1;
|
||||
#define ILibDuktape_net_IPC_BUFFERSIZE 4096
|
||||
typedef struct ILibDuktape_net_WindowsIPC
|
||||
{
|
||||
ILibProcessPipe_Manager manager;
|
||||
duk_context *ctx;
|
||||
void *mServer, *mSocket, *mChain;
|
||||
HANDLE mPipeHandle;
|
||||
ILibProcessPipe_Pipe mPipe;
|
||||
int paused;
|
||||
int totalRead;
|
||||
void *user1;
|
||||
|
||||
OVERLAPPED read_overlapped;
|
||||
OVERLAPPED write_overlapped;
|
||||
OVERLAPPED overlapped;
|
||||
ILibDuktape_DuplexStream *ds;
|
||||
BOOL clientConnected;
|
||||
|
||||
ULONG_PTR _reserved[5];
|
||||
|
||||
int processingRead;
|
||||
char *buffer;
|
||||
int bufferLength;
|
||||
int bufferOffset;
|
||||
@@ -378,13 +381,12 @@ duk_ret_t ILibDuktape_net_socket_connect(duk_context *ctx)
|
||||
ILibDuktape_net_WindowsIPC *winIPC = (ILibDuktape_net_WindowsIPC*)Duktape_PushBuffer(ctx, sizeof(ILibDuktape_net_WindowsIPC));
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_net_WindowsIPC_Buffer);
|
||||
winIPC->overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
winIPC->read_overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
winIPC->write_overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
winIPC->ctx = ctx;
|
||||
winIPC->mSocket = duk_get_heapptr(ctx, -1);
|
||||
winIPC->mChain = Duktape_GetChain(ctx);
|
||||
|
||||
duk_eval_string(ctx, "require('child_process');");
|
||||
winIPC->manager = (ILibProcessPipe_Manager)Duktape_GetPointerProperty(ctx, -1, ILibDuktape_ChildProcess_Manager);
|
||||
duk_pop(ctx);
|
||||
winIPC->mChain = duk_ctx_chain(ctx);
|
||||
winIPC->paused = 1;
|
||||
|
||||
if ((winIPC->mPipeHandle = CreateFileA(path, GENERIC_READ | FILE_WRITE_DATA, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0)) == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
@@ -395,7 +397,6 @@ duk_ret_t ILibDuktape_net_socket_connect(duk_context *ctx)
|
||||
{
|
||||
// SUCCESS
|
||||
winIPC->ds = ILibDuktape_DuplexStream_InitEx(winIPC->ctx, ILibDuktape_net_server_IPC_WriteSink, ILibDuktape_net_server_IPC_EndSink, ILibDuktape_net_server_IPC_PauseSink, ILibDuktape_net_server_IPC_ResumeSink, ILibDuktape_net_server_IPC_unshiftSink, winIPC);
|
||||
winIPC->mPipe = ILibProcessPipe_Pipe_CreateFromExisting(winIPC->manager, winIPC->mPipeHandle, ILibProcessPipe_Pipe_ReaderHandleType_Overlapped);
|
||||
winIPC->ds->readableStream->paused = 1;
|
||||
ILibDuktape_EventEmitter_AddHook(ILibDuktape_EventEmitter_GetEmitter(winIPC->ctx, -1), "data", ILibDuktape_net_socket_ipc_dataHookCallback);
|
||||
ILibDuktape_EventEmitter_AddHook(ILibDuktape_EventEmitter_GetEmitter(winIPC->ctx, -1), "end", ILibDuktape_net_socket_ipc_dataHookCallback);
|
||||
@@ -838,7 +839,99 @@ void ILibDuktape_net_server_OnSendOK(ILibAsyncServerSocket_ServerModule AsyncSer
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
extern void ILibProcessPipe_FreePipe(ILibProcessPipe_Pipe pipeObject);
|
||||
BOOL ILibDuktape_server_ipc_ReadSink(void *chain, HANDLE h, ILibWaitHandle_ErrorStatus status, char *buffer, int bytesRead, void* user)
|
||||
{
|
||||
ILibDuktape_net_WindowsIPC *winIPC = (ILibDuktape_net_WindowsIPC*)user;
|
||||
int consumed = 0;
|
||||
|
||||
if (status == ILibWaitHandle_ErrorStatus_NONE)
|
||||
{
|
||||
winIPC->totalRead += bytesRead;
|
||||
do
|
||||
{
|
||||
winIPC->unshiftedBytes = 0;
|
||||
if (winIPC->totalRead > 0)
|
||||
{
|
||||
ILibDuktape_DuplexStream_WriteData(winIPC->ds, winIPC->buffer + winIPC->bufferOffset, winIPC->totalRead);
|
||||
}
|
||||
if (winIPC->unshiftedBytes > winIPC->totalRead) { winIPC->unshiftedBytes = winIPC->totalRead; }
|
||||
winIPC->bufferOffset += (winIPC->totalRead - winIPC->unshiftedBytes);
|
||||
winIPC->totalRead -= (winIPC->totalRead - winIPC->unshiftedBytes);
|
||||
} while (winIPC->paused == 0 && consumed != 0 && winIPC->totalRead > 0);
|
||||
if (winIPC->totalRead == 0) { winIPC->bufferOffset = 0; }
|
||||
if (winIPC->paused == 0)
|
||||
{
|
||||
if (winIPC->bufferOffset > 0)
|
||||
{
|
||||
memmove_s(winIPC->buffer, winIPC->bufferLength, winIPC->buffer + winIPC->bufferOffset, winIPC->totalRead);
|
||||
winIPC->bufferOffset = 0;
|
||||
}
|
||||
else if (winIPC->totalRead == winIPC->bufferLength)
|
||||
{
|
||||
ILibMemory_ReallocateRaw(&(winIPC->buffer), winIPC->bufferLength == 0 ? ILibDuktape_net_IPC_BUFFERSIZE : winIPC->bufferLength * 2);
|
||||
winIPC->bufferLength = winIPC->bufferLength == 0 ? ILibDuktape_net_IPC_BUFFERSIZE : winIPC->bufferLength * 2;
|
||||
}
|
||||
ILibChain_ReadEx(chain, h, &(winIPC->read_overlapped), winIPC->buffer + winIPC->bufferOffset + winIPC->totalRead, winIPC->bufferLength - winIPC->totalRead, ILibDuktape_server_ipc_ReadSink, winIPC);
|
||||
return(TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
return(FALSE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// I/O Errors
|
||||
ILibDuktape_DuplexStream_Closed(winIPC->ds);
|
||||
return(FALSE);
|
||||
}
|
||||
}
|
||||
BOOL ILibDuktape_server_ipc_WriteSink(void *chain, HANDLE h, ILibWaitHandle_ErrorStatus status, int bytesWritten, void* user)
|
||||
{
|
||||
if (!ILibMemory_CanaryOK(user)) { return(FALSE); }
|
||||
ILibDuktape_net_WindowsIPC *winIPC = (ILibDuktape_net_WindowsIPC*)user;
|
||||
duk_idx_t top = duk_get_top(winIPC->ctx);
|
||||
duk_size_t bufLen;
|
||||
char *buf;
|
||||
ILibTransport_DoneState d = ILibTransport_DoneState_COMPLETE;
|
||||
BOOL ret;
|
||||
|
||||
duk_push_heapptr(winIPC->ctx, winIPC->mSocket); // [obj]
|
||||
duk_get_prop_string(winIPC->ctx, -1, ILibDuktape_net_WindowsIPC_PendingArray); // [obj][array]
|
||||
|
||||
while (d == ILibTransport_DoneState_COMPLETE)
|
||||
{
|
||||
duk_dup(winIPC->ctx, -1); // [obj][array][array]
|
||||
duk_get_prop_string(winIPC->ctx, -1, "shift"); // [obj][array][array][shift]
|
||||
duk_swap_top(winIPC->ctx, -2); // [obj][array][shift][this]
|
||||
if (duk_pcall_method(winIPC->ctx, 0) != 0) { duk_set_top(winIPC->ctx, top); return(FALSE); } // [obj][array][buffer]
|
||||
duk_pop(winIPC->ctx); // [obj][array]
|
||||
if (duk_get_length(winIPC->ctx, -1) == 0) { break; }
|
||||
duk_get_prop_index(winIPC->ctx, -1, 0); // [obj][array][buffer]
|
||||
buf = Duktape_GetBuffer(winIPC->ctx, -1, &bufLen);
|
||||
d = ILibChain_WriteEx(chain, h, &(winIPC->write_overlapped), buf, (int)bufLen, ILibDuktape_server_ipc_WriteSink, winIPC);
|
||||
duk_pop(winIPC->ctx); // [obj][array]
|
||||
}
|
||||
|
||||
switch (d)
|
||||
{
|
||||
case ILibTransport_DoneState_COMPLETE:
|
||||
// No more pending writes, so we can emit drain
|
||||
ILibDuktape_DuplexStream_Ready(winIPC->ds);
|
||||
ret = FALSE;
|
||||
break;
|
||||
case ILibTransport_DoneState_INCOMPLETE:
|
||||
// Still pending writes, so return TRUE, so we can get evented later
|
||||
ret = TRUE;
|
||||
break;
|
||||
case ILibTransport_DoneState_ERROR:
|
||||
ret = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
duk_set_top(winIPC->ctx, top); // ...
|
||||
return(ret);
|
||||
}
|
||||
|
||||
int ILibDuktape_net_server_IPC_unshiftSink(ILibDuktape_DuplexStream *sender, int unshiftBytes, void *user)
|
||||
{
|
||||
@@ -847,184 +940,29 @@ int ILibDuktape_net_server_IPC_unshiftSink(ILibDuktape_DuplexStream *sender, int
|
||||
winIPC->unshiftedBytes = unshiftBytes;
|
||||
return(unshiftBytes);
|
||||
}
|
||||
void ILibDuktape_net_server_IPC_readsink_safe(void *chain, void *user)
|
||||
{
|
||||
if (!ILibMemory_CanaryOK(user)) { return; }
|
||||
ILibDuktape_net_WindowsIPC *winIPC = (ILibDuktape_net_WindowsIPC*)user;
|
||||
ILibProcessPipe_Pipe sender = (ILibProcessPipe_Pipe)winIPC->_reserved[0];
|
||||
DWORD dwErrorCode = (DWORD)winIPC->_reserved[2];
|
||||
char *buffer = (char*)winIPC->_reserved[3];
|
||||
int bufferLen = (int)winIPC->_reserved[4];
|
||||
|
||||
if (dwErrorCode == 0)
|
||||
{
|
||||
winIPC->bytesLeft += bufferLen;
|
||||
ILibDuktape_net_server_IPC_ResumeSink(winIPC->ds, winIPC);
|
||||
}
|
||||
else
|
||||
{
|
||||
ILibDuktape_DuplexStream_Closed(winIPC->ds);
|
||||
ILibProcessPipe_FreePipe(winIPC->mPipe);
|
||||
winIPC->mPipe = NULL; winIPC->mPipeHandle = NULL;
|
||||
|
||||
if (winIPC->mServer != NULL)
|
||||
{
|
||||
// Server IPC, so we can create a new Instance, and listen for a connection
|
||||
duk_context *ctx = winIPC->ctx; // We need to dereference this, because winIPC will go out of scope when we call listen
|
||||
CloseHandle(winIPC->overlapped.hEvent); winIPC->overlapped.hEvent = NULL;
|
||||
if (winIPC->buffer != NULL) { free(winIPC->buffer); winIPC->buffer = NULL; }
|
||||
|
||||
duk_push_heapptr(winIPC->ctx, winIPC->mSocket); // [connection]
|
||||
duk_del_prop_string(ctx, -1, ILibDuktape_net_WindowsIPC_Buffer); duk_pop(winIPC->ctx); // ...
|
||||
|
||||
duk_push_heapptr(ctx, winIPC->mServer); // [server]
|
||||
if (Duktape_GetBooleanProperty(ctx, -1, ILibDuktape_net_server_closed, 0) == 0)
|
||||
{
|
||||
duk_get_prop_string(ctx, -1, "listen"); // [server][listen]
|
||||
duk_swap_top(ctx, -2); // [listen][this]
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_SERVER2LISTENOPTIONS); // [listen][this][options]
|
||||
duk_pcall_method(ctx, 1); // [ret]
|
||||
}
|
||||
else if (Duktape_GetBooleanProperty(ctx, -1, ILibDuktape_net_server_closed_needEmit, 0) != 0)
|
||||
{
|
||||
duk_push_false(ctx); duk_put_prop_string(ctx, -2, ILibDuktape_net_server_closed_needEmit);
|
||||
ILibDuktape_EventEmitter_SetupEmit(ctx, winIPC->mServer, "close"); // [emit][this][closed]
|
||||
duk_pcall_method(ctx, 1); // [ret]
|
||||
}
|
||||
duk_pop(ctx); // ...
|
||||
}
|
||||
}
|
||||
}
|
||||
void ILibDuktape_net_server_IPC_readsink(ILibProcessPipe_Pipe sender, void *user, DWORD dwErrorCode, char *buffer, int bufferLen)
|
||||
{
|
||||
ILibDuktape_net_WindowsIPC *winIPC = (ILibDuktape_net_WindowsIPC*)user;
|
||||
if (!ILibMemory_CanaryOK(user)) { return; }
|
||||
|
||||
winIPC->_reserved[0] = (ULONG_PTR)sender;
|
||||
winIPC->_reserved[1] = (ULONG_PTR)user;
|
||||
winIPC->_reserved[2] = (ULONG_PTR)dwErrorCode;
|
||||
winIPC->_reserved[3] = (ULONG_PTR)buffer;
|
||||
winIPC->_reserved[4] = (ULONG_PTR)bufferLen;
|
||||
|
||||
Duktape_RunOnEventLoop(winIPC->mChain, duk_ctx_nonce(winIPC->ctx), winIPC->ctx, ILibDuktape_net_server_IPC_readsink_safe, NULL, winIPC);
|
||||
}
|
||||
void ILibDuktape_net_server_IPC_PauseSink(ILibDuktape_DuplexStream *sender, void *user)
|
||||
{
|
||||
// No-OP, becuase all we need to so is set Paused flag, which is already the case when we get here
|
||||
ILibDuktape_net_WindowsIPC *winIPC = (ILibDuktape_net_WindowsIPC*)user;
|
||||
winIPC->paused = 1;
|
||||
}
|
||||
void ILibDuktape_net_server_IPC_ResumeSink(ILibDuktape_DuplexStream *sender, void *user)
|
||||
{
|
||||
ILibDuktape_net_WindowsIPC *winIPC = (ILibDuktape_net_WindowsIPC*)user;
|
||||
if (winIPC->processingRead != 0 || winIPC->mPipeHandle == NULL) { return; }
|
||||
winIPC->processingRead = 1;
|
||||
|
||||
if (winIPC->buffer == NULL)
|
||||
{
|
||||
winIPC->buffer = ILibMemory_Allocate(ILibDuktape_net_IPC_BUFFERSIZE, 0, NULL, NULL);
|
||||
winIPC->bufferLength = ILibDuktape_net_IPC_BUFFERSIZE;
|
||||
winIPC->bufferOffset = 0;
|
||||
winIPC->bytesLeft = 0;
|
||||
}
|
||||
|
||||
if (winIPC->bytesLeft <= 0)
|
||||
{
|
||||
winIPC->bytesLeft = 0;
|
||||
winIPC->bufferOffset = 0;
|
||||
if (ILibProcessPipe_Pipe_ReadEx(winIPC->mPipe, winIPC->buffer, winIPC->bufferLength, winIPC, ILibDuktape_net_server_IPC_readsink) != 0)
|
||||
{
|
||||
ILibDuktape_net_server_IPC_readsink(winIPC->mPipe, winIPC, 1, NULL, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check to see if we can drain any of the buffer first
|
||||
while (winIPC->ds->readableStream->paused == 0)
|
||||
{
|
||||
winIPC->unshiftedBytes = 0;
|
||||
ILibDuktape_DuplexStream_WriteData(winIPC->ds, winIPC->buffer + winIPC->bufferOffset, winIPC->bytesLeft);
|
||||
if (winIPC->unshiftedBytes > 0)
|
||||
{
|
||||
if (winIPC->unshiftedBytes == winIPC->bytesLeft)
|
||||
{
|
||||
// Unshift the entire buffer
|
||||
winIPC->unshiftedBytes = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unshift some of the buffer
|
||||
winIPC->bufferOffset += (winIPC->bytesLeft - winIPC->unshiftedBytes);
|
||||
if (winIPC->bytesLeft == winIPC->unshiftedBytes)
|
||||
{
|
||||
winIPC->unshiftedBytes = 0;
|
||||
}
|
||||
winIPC->bytesLeft = winIPC->unshiftedBytes;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
winIPC->bufferOffset = winIPC->bytesLeft = 0;
|
||||
}
|
||||
|
||||
if (winIPC->ds->readableStream->paused == 0 && (winIPC->bytesLeft == 0 || (winIPC->bytesLeft > 0 && winIPC->unshiftedBytes == 0)))
|
||||
{
|
||||
if (winIPC->bufferLength - winIPC->bufferOffset - winIPC->bytesLeft == 0)
|
||||
{
|
||||
// We need to grow the buffer
|
||||
ILibMemory_ReallocateRaw(&(winIPC->buffer), winIPC->bufferLength + ILibDuktape_net_IPC_BUFFERSIZE);
|
||||
winIPC->bufferLength += ILibDuktape_net_IPC_BUFFERSIZE;
|
||||
}
|
||||
if (ILibProcessPipe_Pipe_ReadEx(winIPC->mPipe, winIPC->buffer + winIPC->bufferOffset + winIPC->bytesLeft, winIPC->bufferLength - winIPC->bufferOffset - winIPC->bytesLeft, winIPC, ILibDuktape_net_server_IPC_readsink) != 0)
|
||||
{
|
||||
ILibDuktape_net_server_IPC_readsink(winIPC->mPipe, winIPC, 1, NULL, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
winIPC->processingRead = 0;
|
||||
winIPC->paused = 0;
|
||||
ILibDuktape_server_ipc_ReadSink(winIPC->mChain, winIPC->mPipeHandle, ILibWaitHandle_ErrorStatus_NONE, NULL, 0, winIPC);
|
||||
}
|
||||
void ILibDuktape_net_server_IPC_WriteCompletionEvent(ILibProcessPipe_Pipe sender, void *user, DWORD errorCode, int bytesWritten)
|
||||
{
|
||||
if (!ILibMemory_CanaryOK(user) || errorCode != 0) { return; }
|
||||
ILibDuktape_net_WindowsIPC *winIPC = (ILibDuktape_net_WindowsIPC*)user;
|
||||
duk_idx_t top = duk_get_top(winIPC->ctx);
|
||||
|
||||
duk_push_heapptr(winIPC->ctx, winIPC->mSocket); // [obj]
|
||||
duk_get_prop_string(winIPC->ctx, -1, ILibDuktape_net_WindowsIPC_PendingArray); // [obj][array]
|
||||
duk_get_prop_string(winIPC->ctx, -1, "shift"); // [obj][array][shift]
|
||||
duk_dup(winIPC->ctx, -2); // [obj][array][shift][this]
|
||||
if (duk_pcall_method(winIPC->ctx, 0) != 0) // [obj][array][buffer]
|
||||
{
|
||||
ILibDuktape_Process_UncaughtExceptionEx(winIPC->ctx, "Internal Error: net.socket.ipc.writeCompletionEvent");
|
||||
duk_set_top(winIPC->ctx, top); // ...
|
||||
return;
|
||||
}
|
||||
duk_pop(winIPC->ctx); // [obj][array]
|
||||
if (duk_get_length(winIPC->ctx, -1) > 0)
|
||||
{
|
||||
// Still pending Writes
|
||||
duk_get_prop_index(winIPC->ctx, -1, 0); // [obj][array][buffer]
|
||||
duk_size_t bufLen;
|
||||
char *buf = (char*)Duktape_GetBuffer(winIPC->ctx, -1, &bufLen);
|
||||
duk_set_top(winIPC->ctx, top); // ...
|
||||
ILibProcessPipe_Pipe_WriteEx(winIPC->mPipe, buf, (int)bufLen, winIPC, ILibDuktape_net_server_IPC_WriteCompletionEvent);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No more pending writes, so we can emit drain
|
||||
duk_set_top(winIPC->ctx, top); // ...
|
||||
ILibDuktape_DuplexStream_Ready(winIPC->ds);
|
||||
}
|
||||
}
|
||||
ILibTransport_DoneState ILibDuktape_net_server_IPC_WriteSink(ILibDuktape_DuplexStream *stream, char *buffer, int bufferLen, void *user)
|
||||
{
|
||||
if (!ILibMemory_CanaryOK(user)) { return(ILibTransport_DoneState_ERROR); }
|
||||
ILibDuktape_net_WindowsIPC *winIPC = (ILibDuktape_net_WindowsIPC*)user;
|
||||
|
||||
if (!duk_ctx_is_alive(winIPC->ctx) || winIPC->mPipeHandle == NULL) { return(ILibTransport_DoneState_ERROR); }
|
||||
|
||||
duk_push_heapptr(winIPC->ctx, winIPC->mSocket); // [obj]
|
||||
duk_get_prop_string(winIPC->ctx, -1, ILibDuktape_net_WindowsIPC_PendingArray); // [obj][array]
|
||||
|
||||
|
||||
char *q = duk_push_fixed_buffer(winIPC->ctx, bufferLen); // [obj][array][buffer]
|
||||
duk_size_t len = duk_get_length(winIPC->ctx, -2);
|
||||
duk_put_prop_index(winIPC->ctx, -2, (duk_uarridx_t)len); // [obj][array]
|
||||
@@ -1034,7 +972,15 @@ ILibTransport_DoneState ILibDuktape_net_server_IPC_WriteSink(ILibDuktape_DuplexS
|
||||
if (len == 0)
|
||||
{
|
||||
// No Pending Writes
|
||||
ILibProcessPipe_Pipe_WriteEx(winIPC->mPipe, q, bufferLen, winIPC, ILibDuktape_net_server_IPC_WriteCompletionEvent);
|
||||
ILibTransport_DoneState ret = ILibChain_WriteEx(winIPC->mChain, winIPC->mPipeHandle, &(winIPC->write_overlapped), q, bufferLen, ILibDuktape_server_ipc_WriteSink, winIPC);
|
||||
if (ret != ILibTransport_DoneState_INCOMPLETE)
|
||||
{
|
||||
duk_push_heapptr(winIPC->ctx, winIPC->mSocket); // [obj]
|
||||
duk_get_prop_string(winIPC->ctx, -1, ILibDuktape_net_WindowsIPC_PendingArray); // [obj][array]
|
||||
duk_array_shift(winIPC->ctx, -1); // [obj][array][val]
|
||||
duk_pop_3(winIPC->ctx); // ...
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
|
||||
return(ILibTransport_DoneState_INCOMPLETE);
|
||||
@@ -1044,22 +990,21 @@ void ILibDuktape_net_server_IPC_EndSink(ILibDuktape_DuplexStream *stream, void *
|
||||
if (!ILibMemory_CanaryOK(user)) { return; }
|
||||
ILibDuktape_net_WindowsIPC *winIPC = (ILibDuktape_net_WindowsIPC*)user;
|
||||
|
||||
if (ILibProcessPipe_Pipe_CancelEx(winIPC->mPipe) == 0)
|
||||
{
|
||||
ILibProcessPipe_FreePipe(winIPC->mPipe);
|
||||
winIPC->mPipe = NULL; winIPC->mPipeHandle = NULL;
|
||||
if (winIPC->mServer != NULL)
|
||||
{
|
||||
// Server IPC, so we can create a new Instance, and listen for a connection
|
||||
duk_context *ctx = winIPC->ctx; // We need to dereference this, because winIPC will go out of scope when we call listen
|
||||
CloseHandle(winIPC->overlapped.hEvent); winIPC->overlapped.hEvent = NULL;
|
||||
if (winIPC->mPipeHandle != NULL) { CloseHandle(winIPC->mPipeHandle); winIPC->mPipeHandle = NULL; }
|
||||
if (winIPC->read_overlapped.hEvent != NULL) { CloseHandle(winIPC->read_overlapped.hEvent); winIPC->read_overlapped.hEvent = NULL; }
|
||||
if (winIPC->write_overlapped.hEvent != NULL) { CloseHandle(winIPC->write_overlapped.hEvent); winIPC->write_overlapped.hEvent = NULL; }
|
||||
|
||||
duk_push_heapptr(ctx, winIPC->mServer); // [server]
|
||||
duk_get_prop_string(ctx, -1, "listen"); // [server][listen]
|
||||
duk_swap_top(ctx, -2); // [listen][this]
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_SERVER2LISTENOPTIONS); // [listen][this][options]
|
||||
duk_pcall_method(ctx, 1); duk_pop(ctx); // ...
|
||||
}
|
||||
if (winIPC->mServer != NULL)
|
||||
{
|
||||
// Server IPC, so we can create a new Instance, and listen for a connection
|
||||
duk_context *ctx = winIPC->ctx; // We need to dereference this, because winIPC will go out of scope when we call listen
|
||||
CloseHandle(winIPC->overlapped.hEvent); winIPC->overlapped.hEvent = NULL;
|
||||
|
||||
duk_push_heapptr(ctx, winIPC->mServer); // [server]
|
||||
duk_get_prop_string(ctx, -1, "listen"); // [server][listen]
|
||||
duk_swap_top(ctx, -2); // [listen][this]
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_SERVER2LISTENOPTIONS); // [listen][this][options]
|
||||
duk_pcall_method(ctx, 1); duk_pop(ctx); // ...
|
||||
}
|
||||
}
|
||||
duk_ret_t ILibDuktape_net_server_IPC_ConnectSink_Finalizer(duk_context *ctx)
|
||||
@@ -1067,22 +1012,35 @@ duk_ret_t ILibDuktape_net_server_IPC_ConnectSink_Finalizer(duk_context *ctx)
|
||||
ILibDuktape_net_WindowsIPC *winIPC = (ILibDuktape_net_WindowsIPC*)Duktape_GetBufferProperty(ctx, 0, ILibDuktape_net_WindowsIPC_Buffer);
|
||||
if (winIPC != NULL)
|
||||
{
|
||||
if (winIPC->mPipe != NULL && winIPC->mPipeHandle != NULL)
|
||||
if (winIPC->mPipeHandle != NULL)
|
||||
{
|
||||
// It's ok to do this, becuase the CancelEx happens on the same thread, and the completion routine will use an APC Queue, so the Canary will fail before it tries to deref
|
||||
ILibProcessPipe_Pipe_CancelEx(winIPC->mPipe);
|
||||
ILibProcessPipe_FreePipe(winIPC->mPipe);
|
||||
winIPC->mPipe = NULL; winIPC->mPipeHandle = NULL;
|
||||
CloseHandle(winIPC->mPipeHandle);
|
||||
winIPC->mPipeHandle = NULL;
|
||||
}
|
||||
if (winIPC->buffer != NULL) { free(winIPC->buffer); winIPC->buffer = NULL; }
|
||||
if (winIPC->read_overlapped.hEvent != NULL)
|
||||
{
|
||||
ILibChain_RemoveWaitHandle(duk_ctx_chain(ctx), winIPC->read_overlapped.hEvent);
|
||||
CloseHandle(winIPC->read_overlapped.hEvent);
|
||||
winIPC->read_overlapped.hEvent = NULL;
|
||||
}
|
||||
if (winIPC->write_overlapped.hEvent != NULL)
|
||||
{
|
||||
ILibChain_RemoveWaitHandle(duk_ctx_chain(ctx), winIPC->write_overlapped.hEvent);
|
||||
CloseHandle(winIPC->write_overlapped.hEvent);
|
||||
winIPC->write_overlapped.hEvent = NULL;
|
||||
}
|
||||
|
||||
if (winIPC->buffer != NULL) { free(winIPC->buffer); }
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
BOOL ILibDuktape_net_server_IPC_ConnectSink(HANDLE event, ILibWaitHandle_ErrorStatus status, void* user)
|
||||
//BOOL ILibDuktape_net_server_IPC_ConnectSink(HANDLE event, ILibWaitHandle_ErrorStatus status, void* user)
|
||||
BOOL ILibDuktape_net_server_IPC_ConnectSink(void *chain, HANDLE event, ILibWaitHandle_ErrorStatus status, void* user)
|
||||
{
|
||||
if (ILibMemory_CanaryOK(user))
|
||||
if (ILibMemory_CanaryOK(user) && status == ILibWaitHandle_ErrorStatus_NONE)
|
||||
{
|
||||
ILibDuktape_net_WindowsIPC *winIPC = (ILibDuktape_net_WindowsIPC*)user;
|
||||
winIPC->clientConnected = TRUE;
|
||||
ILibDuktape_EventEmitter_SetupEmit(winIPC->ctx, winIPC->mServer, "connection"); // [emit][this][connection]
|
||||
duk_push_object(winIPC->ctx); // [emit][this][connection][socket]
|
||||
ILibDuktape_WriteID(winIPC->ctx, "net.socket.ipc");
|
||||
@@ -1095,8 +1053,9 @@ BOOL ILibDuktape_net_server_IPC_ConnectSink(HANDLE event, ILibWaitHandle_ErrorSt
|
||||
duk_push_array(winIPC->ctx); duk_put_prop_string(winIPC->ctx, -2, ILibDuktape_net_WindowsIPC_PendingArray);
|
||||
winIPC->mSocket = duk_get_heapptr(winIPC->ctx, -1);
|
||||
winIPC->ds = ILibDuktape_DuplexStream_InitEx(winIPC->ctx, ILibDuktape_net_server_IPC_WriteSink, ILibDuktape_net_server_IPC_EndSink, ILibDuktape_net_server_IPC_PauseSink, ILibDuktape_net_server_IPC_ResumeSink, ILibDuktape_net_server_IPC_unshiftSink, winIPC);
|
||||
winIPC->mPipe = ILibProcessPipe_Pipe_CreateFromExisting(winIPC->manager, winIPC->mPipeHandle, ILibProcessPipe_Pipe_ReaderHandleType_Overlapped);
|
||||
winIPC->ds->readableStream->paused = 1;
|
||||
winIPC->paused = 1;
|
||||
|
||||
ILibDuktape_EventEmitter_AddHook(ILibDuktape_EventEmitter_GetEmitter(winIPC->ctx, -1), "data", ILibDuktape_net_socket_ipc_dataHookCallback);
|
||||
ILibDuktape_EventEmitter_AddHook(ILibDuktape_EventEmitter_GetEmitter(winIPC->ctx, -1), "end", ILibDuktape_net_socket_ipc_dataHookCallback);
|
||||
|
||||
@@ -1210,12 +1169,14 @@ duk_ret_t ILibDuktape_net_server_listen(duk_context *ctx)
|
||||
ILibDuktape_net_WindowsIPC *winIPC = (ILibDuktape_net_WindowsIPC*)Duktape_PushBuffer(ctx, sizeof(ILibDuktape_net_WindowsIPC));
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_net_WindowsIPC_Buffer);
|
||||
winIPC->overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
winIPC->read_overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
winIPC->write_overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
winIPC->ctx = ctx;
|
||||
winIPC->mServer = duk_get_heapptr(ctx, -1);
|
||||
winIPC->mChain = Duktape_GetChain(ctx);
|
||||
winIPC->mChain = duk_ctx_chain(ctx);
|
||||
winIPC->clientConnected = FALSE;
|
||||
|
||||
duk_eval_string(ctx, "require('child_process');");
|
||||
winIPC->manager = (ILibProcessPipe_Manager)Duktape_GetPointerProperty(ctx, -1, ILibDuktape_ChildProcess_Manager);
|
||||
duk_pop(ctx);
|
||||
|
||||
if (Duktape_GetBooleanProperty(ctx, 0, "writableAll", 0) != 0)
|
||||
@@ -1252,9 +1213,9 @@ duk_ret_t ILibDuktape_net_server_listen(duk_context *ctx)
|
||||
duk_del_prop_string(ctx, -1, ILibDuktape_net_WindowsIPC_Buffer);
|
||||
return(ILibDuktape_Error(ctx, "Error Creating Named Pipe: %s", ipc));
|
||||
}
|
||||
|
||||
//printf("ConnectNamedPipe(%s)\n", ipc);
|
||||
ConnectNamedPipe(winIPC->mPipeHandle, &winIPC->overlapped);
|
||||
ILibProcessPipe_WaitHandle_Add2(winIPC->manager, winIPC->overlapped.hEvent, winIPC, ILibDuktape_net_server_IPC_ConnectSink);
|
||||
ILibChain_AddWaitHandle(duk_ctx_chain(ctx), winIPC->overlapped.hEvent, -1, ILibDuktape_net_server_IPC_ConnectSink, winIPC);
|
||||
|
||||
if (pIPC_SA != NULL) { LocalFree(IPC_ACL); }
|
||||
return(1);
|
||||
@@ -1334,7 +1295,7 @@ duk_ret_t ILibDuktape_net_server_Finalizer(duk_context *ctx)
|
||||
ILibDuktape_net_WindowsIPC *ipc = Duktape_GetBufferProperty(ctx, 0, ILibDuktape_net_WindowsIPC_Buffer);
|
||||
if (ipc != NULL && ipc->overlapped.hEvent != NULL)
|
||||
{
|
||||
ILibProcessPipe_WaitHandle_Remove(ipc->manager, ipc->overlapped.hEvent);
|
||||
ILibChain_RemoveWaitHandle(duk_ctx_chain(ctx), ipc->overlapped.hEvent);
|
||||
if (ipc->mPipeHandle != NULL) { CloseHandle(ipc->mPipeHandle); ipc->mPipeHandle = NULL; }
|
||||
if (ipc->overlapped.hEvent != NULL) { CloseHandle(ipc->overlapped.hEvent); ipc->overlapped.hEvent = NULL; }
|
||||
}
|
||||
@@ -1399,7 +1360,7 @@ duk_ret_t ILibDuktape_net_server_close(duk_context *ctx)
|
||||
ILibDuktape_net_WindowsIPC *winIPC = (ILibDuktape_net_WindowsIPC*)Duktape_GetBufferProperty(ctx, -1, ILibDuktape_net_WindowsIPC_Buffer);
|
||||
if (winIPC != NULL && winIPC->mPipeHandle != NULL)
|
||||
{
|
||||
if (winIPC->mPipe == NULL)
|
||||
if (winIPC->clientConnected == FALSE)
|
||||
{
|
||||
// Listening
|
||||
DisconnectNamedPipe(winIPC->mPipeHandle);
|
||||
|
||||
Reference in New Issue
Block a user