mirror of
https://github.com/Ylianst/MeshAgent
synced 2025-12-17 16:53:13 +00:00
Improved signal handling on linux, to support all standard signals.
This commit is contained in:
@@ -899,7 +899,6 @@ duk_ret_t ILibDuktape_Process_cwd(duk_context *ctx)
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef _POSIX
|
#ifdef _POSIX
|
||||||
duk_ret_t ILibDuktape_ScriptContainer_Process_SignalListener_Immediate(duk_context *ctx)
|
duk_ret_t ILibDuktape_ScriptContainer_Process_SignalListener_Immediate(duk_context *ctx)
|
||||||
{
|
{
|
||||||
@@ -910,12 +909,6 @@ duk_ret_t ILibDuktape_ScriptContainer_Process_SignalListener_Immediate(duk_conte
|
|||||||
|
|
||||||
switch (((int*)sigbuffer)[1])
|
switch (((int*)sigbuffer)[1])
|
||||||
{
|
{
|
||||||
case SIGTERM:
|
|
||||||
ILibDuktape_EventEmitter_SetupEmit(ctx, h, "SIGTERM"); // [emit][this][SIGTERM]
|
|
||||||
duk_push_string(ctx, SIGTABLE[((int*)sigbuffer)[1]]); // [emit][this][SIGTERM][name]
|
|
||||||
if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "Error Emitting SIGTERM: "); }
|
|
||||||
duk_pop(ctx);
|
|
||||||
break;
|
|
||||||
case SIGCHLD:
|
case SIGCHLD:
|
||||||
s = 0;
|
s = 0;
|
||||||
waitpid(((pid_t*)sigbuffer)[2], &s, 0);
|
waitpid(((pid_t*)sigbuffer)[2], &s, 0);
|
||||||
@@ -928,6 +921,10 @@ duk_ret_t ILibDuktape_ScriptContainer_Process_SignalListener_Immediate(duk_conte
|
|||||||
duk_pop(ctx);
|
duk_pop(ctx);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
ILibDuktape_EventEmitter_SetupEmit(ctx, h, SIGTABLE[((int*)sigbuffer)[1]]); // [emit][this][SIGTERM]
|
||||||
|
duk_push_string(ctx, SIGTABLE[((int*)sigbuffer)[1]]); // [emit][this][SIGTERM][name]
|
||||||
|
if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "Error Emitting %s: ", SIGTABLE[((int*)sigbuffer)[1]]); }
|
||||||
|
duk_pop(ctx);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return(0);
|
return(0);
|
||||||
@@ -996,44 +993,6 @@ void ILibDuktape_ScriptContainer_Process_SignalListener(int signum, siginfo_t *i
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void ILibDuktape_ScriptContainer_Process_SIGTERM_Hook(ILibDuktape_EventEmitter *sender, char *eventName, void *hookedCallback)
|
|
||||||
{
|
|
||||||
int listenerCount = ILibDuktape_EventEmitter_HasListeners2(sender, "SIGTERM", 0);
|
|
||||||
if (listenerCount == 0)
|
|
||||||
{
|
|
||||||
// We are the first
|
|
||||||
#ifdef _POSIX
|
|
||||||
struct sigaction action;
|
|
||||||
memset(&action, 0, sizeof(action));
|
|
||||||
action.sa_sigaction = ILibDuktape_ScriptContainer_Process_SignalListener;
|
|
||||||
sigemptyset(&action.sa_mask);
|
|
||||||
action.sa_flags = SA_SIGINFO;
|
|
||||||
if (sigaction(SIGTERM, &action, NULL) == 0) {}
|
|
||||||
#else
|
|
||||||
UNREFERENCED_PARAMETER(eventName);
|
|
||||||
UNREFERENCED_PARAMETER(hookedCallback);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void ILibDuktape_ScriptContainer_Process_SIGCHLD_Hook(ILibDuktape_EventEmitter *sender, char *eventName, void *hookedCallback)
|
|
||||||
{
|
|
||||||
int listenerCount = ILibDuktape_EventEmitter_HasListeners2(sender, "SIGCHLD", 0);
|
|
||||||
if (listenerCount == 0)
|
|
||||||
{
|
|
||||||
// We are the first
|
|
||||||
#ifdef _POSIX
|
|
||||||
struct sigaction action;
|
|
||||||
memset(&action, 0, sizeof(action));
|
|
||||||
action.sa_sigaction = ILibDuktape_ScriptContainer_Process_SignalListener;
|
|
||||||
sigemptyset(&action.sa_mask);
|
|
||||||
action.sa_flags = SA_SIGINFO;
|
|
||||||
if (sigaction(SIGCHLD, &action, NULL) == 0) {}
|
|
||||||
#else
|
|
||||||
UNREFERENCED_PARAMETER(eventName);
|
|
||||||
UNREFERENCED_PARAMETER(hookedCallback);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
duk_ret_t ILibDuktape_Process_setenv(duk_context *ctx)
|
duk_ret_t ILibDuktape_Process_setenv(duk_context *ctx)
|
||||||
{
|
{
|
||||||
char *name = (char*)duk_require_string(ctx, 0);
|
char *name = (char*)duk_require_string(ctx, 0);
|
||||||
@@ -1136,27 +1095,25 @@ duk_ret_t ILibDuktape_ScriptContainer_Process_rlimit_getter(duk_context *ctx)
|
|||||||
duk_ret_t ILibDuktape_ScriptContainer_removeListenerSink(duk_context *ctx)
|
duk_ret_t ILibDuktape_ScriptContainer_removeListenerSink(duk_context *ctx)
|
||||||
{
|
{
|
||||||
#ifdef _POSIX
|
#ifdef _POSIX
|
||||||
|
int i;
|
||||||
struct sigaction action;
|
struct sigaction action;
|
||||||
char *name = (char*)duk_require_string(ctx, 0);
|
char *name = (char*)duk_require_string(ctx, 0);
|
||||||
duk_push_this(ctx); // [process]
|
duk_push_this(ctx); // [process]
|
||||||
|
|
||||||
if (strcmp(name, "SIGCHLD") == 0 && ILibDuktape_EventEmitter_HasListenersEx(ctx, -1, "SIGCHLD")==0)
|
for (i = 1; i < (sizeof(SIGTABLE) / sizeof(char*)); ++i)
|
||||||
{
|
{
|
||||||
// No more listeners, so we can unhook the sighandler
|
if (strcmp(name, SIGTABLE[i]) == 0)
|
||||||
memset(&action, 0, sizeof(action));
|
{
|
||||||
sigemptyset(&action.sa_mask);
|
if (ILibDuktape_EventEmitter_HasListenersEx(ctx, -1, SIGTABLE[i]) == 0)
|
||||||
action.sa_flags = 0;
|
{
|
||||||
action.sa_handler = SIG_DFL;
|
// No more listeners, so we can unhook the sighandler
|
||||||
if (sigaction(SIGCHLD, &action, NULL) == 0) {}
|
memset(&action, 0, sizeof(action));
|
||||||
}
|
sigemptyset(&action.sa_mask);
|
||||||
if (strcmp(name, "SIGTERM") == 0 && ILibDuktape_EventEmitter_HasListenersEx(ctx, -1, "SIGTERM") == 0)
|
action.sa_flags = 0;
|
||||||
{
|
action.sa_handler = SIG_DFL;
|
||||||
// No more listeners, so we can unhook the sighandler
|
if (sigaction(i, &action, NULL) == 0) {}
|
||||||
memset(&action, 0, sizeof(action));
|
}
|
||||||
sigemptyset(&action.sa_mask);
|
}
|
||||||
action.sa_flags = 0;
|
|
||||||
action.sa_handler = SIG_DFL;
|
|
||||||
if (sigaction(SIGTERM, &action, NULL) == 0) {}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return(0);
|
return(0);
|
||||||
@@ -1191,6 +1148,7 @@ void ILibDuktape_Process_SemaphoreTracking_sink(char *source, void *user, int in
|
|||||||
ILibSemaphoreTrack_func = NULL;
|
ILibSemaphoreTrack_func = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
duk_ret_t ILibDuktape_Process_SemaphoreTracking(duk_context *ctx)
|
duk_ret_t ILibDuktape_Process_SemaphoreTracking(duk_context *ctx)
|
||||||
{
|
{
|
||||||
if (duk_require_boolean(ctx, 0) != 0)
|
if (duk_require_boolean(ctx, 0) != 0)
|
||||||
@@ -1209,6 +1167,35 @@ duk_ret_t ILibDuktape_Process_SemaphoreTracking(duk_context *ctx)
|
|||||||
}
|
}
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
duk_ret_t ILibDuktape_Process_SignalHooks(duk_context *ctx)
|
||||||
|
{
|
||||||
|
#ifdef _POSIX
|
||||||
|
int i;
|
||||||
|
char *eventname = (char*)duk_require_string(ctx, 0);
|
||||||
|
ILibDuktape_EventEmitter *emitter = ILibDuktape_EventEmitter_GetEmitter_fromThis(ctx);
|
||||||
|
|
||||||
|
for (i = 1; i < (sizeof(SIGTABLE) / sizeof(char*)); ++i)
|
||||||
|
{
|
||||||
|
if (strcmp(eventname, SIGTABLE[i]) == 0)
|
||||||
|
{
|
||||||
|
if (ILibDuktape_EventEmitter_HasListeners2(emitter, eventname, 0) == 0)
|
||||||
|
{
|
||||||
|
// We are the first listener, so we need to set the signal handler
|
||||||
|
struct sigaction action;
|
||||||
|
memset(&action, 0, sizeof(action));
|
||||||
|
action.sa_sigaction = ILibDuktape_ScriptContainer_Process_SignalListener;
|
||||||
|
sigemptyset(&action.sa_mask);
|
||||||
|
action.sa_flags = SA_SIGINFO;
|
||||||
|
if (sigaction(i, &action, NULL) == 0) {}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
void ILibDuktape_ScriptContainer_Process_Init(duk_context *ctx, char **argList)
|
void ILibDuktape_ScriptContainer_Process_Init(duk_context *ctx, char **argList)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@@ -1379,10 +1366,12 @@ void ILibDuktape_ScriptContainer_Process_Init(duk_context *ctx, char **argList)
|
|||||||
ILibDuktape_CreateProperty_InstanceMethod(ctx, "exit", ILibDuktape_ScriptContainer_Process_Exit, DUK_VARARGS);
|
ILibDuktape_CreateProperty_InstanceMethod(ctx, "exit", ILibDuktape_ScriptContainer_Process_Exit, DUK_VARARGS);
|
||||||
ILibDuktape_CreateProperty_InstanceMethod(ctx, "_exit", ILibDuktape_ScriptContainer_Process_ExitEx, DUK_VARARGS);
|
ILibDuktape_CreateProperty_InstanceMethod(ctx, "_exit", ILibDuktape_ScriptContainer_Process_ExitEx, DUK_VARARGS);
|
||||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "uncaughtException");
|
ILibDuktape_EventEmitter_CreateEventEx(emitter, "uncaughtException");
|
||||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "SIGTERM");
|
|
||||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "SIGCHLD");
|
for (i = 1; i < 31; ++i)
|
||||||
ILibDuktape_EventEmitter_AddHook(emitter, "SIGTERM", ILibDuktape_ScriptContainer_Process_SIGTERM_Hook);
|
{
|
||||||
ILibDuktape_EventEmitter_AddHook(emitter, "SIGCHLD", ILibDuktape_ScriptContainer_Process_SIGCHLD_Hook);
|
ILibDuktape_EventEmitter_CreateEventEx(emitter, SIGTABLE[i]);
|
||||||
|
}
|
||||||
|
ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "newListener", ILibDuktape_Process_SignalHooks);
|
||||||
ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "removeListener", ILibDuktape_ScriptContainer_removeListenerSink);
|
ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "removeListener", ILibDuktape_ScriptContainer_removeListenerSink);
|
||||||
ILibDuktape_CreateEventWithGetter(ctx, "exitting", ILibDuktape_Process_Exitting);
|
ILibDuktape_CreateEventWithGetter(ctx, "exitting", ILibDuktape_Process_Exitting);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user