summaryrefslogtreecommitdiff
path: root/core/src
diff options
context:
space:
mode:
authorruki <[email protected]>2024-03-28 23:01:07 +0800
committerruki <[email protected]>2024-03-28 23:01:07 +0800
commit024b14ed93b1bc7e3b30d8dc68105ce2cb5016d6 (patch)
tree0f41435fe2ba5f0e9cb919174d957b35d2cf3dbd /core/src
parent4d4edd5ba69932b2206c891a18dee0f734327767 (diff)
add os.signal #4889
Diffstat (limited to 'core/src')
-rw-r--r--core/src/xmake/engine.c2
-rw-r--r--core/src/xmake/os/signal.c140
2 files changed, 142 insertions, 0 deletions
diff --git a/core/src/xmake/engine.c b/core/src/xmake/engine.c
index d79f59d6a..cbe1ed4fc 100644
--- a/core/src/xmake/engine.c
+++ b/core/src/xmake/engine.c
@@ -122,6 +122,7 @@ tb_int_t xm_os_syserror(lua_State* lua);
tb_int_t xm_os_strerror(lua_State* lua);
tb_int_t xm_os_getwinsize(lua_State* lua);
tb_int_t xm_os_getpid(lua_State* lua);
+tb_int_t xm_os_signal(lua_State* lua);
#ifndef TB_CONFIG_OS_WINDOWS
tb_int_t xm_os_uid(lua_State* lua);
tb_int_t xm_os_gid(lua_State* lua);
@@ -344,6 +345,7 @@ static luaL_Reg const g_os_functions[] =
, { "filesize", xm_os_filesize }
, { "getwinsize", xm_os_getwinsize}
, { "getpid", xm_os_getpid }
+, { "signal", xm_os_signal }
#ifndef TB_CONFIG_OS_WINDOWS
, { "uid", xm_os_uid }
, { "gid", xm_os_gid }
diff --git a/core/src/xmake/os/signal.c b/core/src/xmake/os/signal.c
new file mode 100644
index 000000000..3955dc5d3
--- /dev/null
+++ b/core/src/xmake/os/signal.c
@@ -0,0 +1,140 @@
+/*!A cross-platform build utility based on Lua
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Copyright (C) 2015-present, TBOOX Open Source Group.
+ *
+ * @author ruki
+ * @file signal.c
+ *
+ */
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * trace
+ */
+#define TB_TRACE_MODULE_NAME "signal"
+#define TB_TRACE_MODULE_DEBUG (0)
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * includes
+ */
+#include "prefix.h"
+#if defined(TB_CONFIG_OS_MACOSX) || defined(TB_CONFIG_OS_IOS)
+# include <unistd.h>
+# include <signal.h>
+#elif defined(TB_CONFIG_OS_LINUX) || defined(TB_CONFIG_OS_BSD) || defined(TB_CONFIG_OS_ANDROID) || defined(TB_CONFIG_OS_HAIKU)
+# include <unistd.h>
+# include <signal.h>
+#endif
+#ifdef TB_CONFIG_OS_BSD
+# include <sys/types.h>
+# include <sys/sysctl.h>
+# include <signal.h>
+#endif
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * types
+ */
+typedef enum __xm_os_signal_e {
+ XM_OS_SIGINT = 1
+}xm_os_signal_e;
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * globals
+ */
+static lua_State* g_lua = tb_null;
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * private implementation
+ */
+static tb_void_t xm_os_signal_handler_impl(tb_int_t signo_native)
+{
+ // do callback(signo)
+ lua_State* lua = g_lua;
+ if (lua)
+ {
+ tb_int_t signo = -1;
+ switch (signo_native)
+ {
+#ifdef SIGINT
+ case SIGINT:
+ signo = XM_OS_SIGINT;
+ break;
+#endif
+ default:
+ break;
+ }
+ if (signo >= 0)
+ {
+ tb_char_t name[64] = {0};
+ tb_snprintf(name, sizeof(name), "_SIGNAL_HANDLER_%d", signo);
+ lua_getglobal(lua, name);
+ lua_pushinteger(lua, signo);
+ lua_call(lua, 1, 0);
+ }
+ }
+}
+
+#if defined(TB_CONFIG_OS_WINDOWS)
+static BOOL WINAPI xm_os_signal_handler(DWORD signo)
+{
+ xm_os_signal_handler_impl((tb_int_t)signo)
+ return TRUE;
+}
+#elif defined(SIGINT)
+static tb_void_t xm_os_signal_handler(tb_int_t signo)
+{
+ xm_os_signal_handler_impl(signo);
+}
+#endif
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * implementation
+ */
+tb_int_t xm_os_signal(lua_State* lua)
+{
+ // check
+ tb_assert_and_check_return_val(lua, 0);
+ g_lua = lua;
+
+ // check signal handler
+ if (!lua_isfunction(lua, 2))
+ return 0;
+
+ // save signal handler
+ tb_int_t signo = (tb_int_t)luaL_checkinteger(lua, 1);
+ tb_char_t name[64] = {0};
+ tb_snprintf(name, sizeof(name), "_SIGNAL_HANDLER_%d", signo);
+ lua_pushvalue(lua, 2);
+ lua_setglobal(lua, name);
+
+#if defined(TB_CONFIG_OS_WINDOWS)
+ if (signo == XM_OS_SIGINT)
+ SetConsoleCtrlHandler(xm_os_signal_handler, TRUE);
+#elif defined(SIGINT) // for checking signal
+ tb_int_t signo_native = -1;
+ switch (signo)
+ {
+ case XM_OS_SIGINT:
+#ifdef SIGINT
+ signo_native = SIGINT;
+#endif
+ break;
+ default:
+ break;
+ }
+ if (signo_native >= 0)
+ signal(signo_native, xm_os_signal_handler);
+#endif
+ return 0;
+}