Skip to content

Commit

Permalink
Merge pull request #4890 from xmake-io/signal
Browse files Browse the repository at this point in the history
add os.signal #4889
  • Loading branch information
waruqi committed Mar 28, 2024
2 parents 4d4edd5 + d66e573 commit 1520125
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 0 deletions.
2 changes: 2 additions & 0 deletions core/src/xmake/engine.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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 }
Expand Down
137 changes: 137 additions & 0 deletions core/src/xmake/os/signal.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
/*!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)
{
// do callback(signo)
lua_State* lua = g_lua;
if (lua)
{
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 ctrl_type)
{
if (ctrl_type == CTRL_C_EVENT)
xm_os_signal_handler_impl(XM_OS_SIGINT);
return TRUE;
}
#elif defined(SIGINT)
static tb_void_t xm_os_signal_handler(tb_int_t signo_native)
{
tb_int_t signo = -1;
switch (signo_native)
{
case SIGINT:
signo = XM_OS_SIGINT;
break;
default:
break;
}
if (signo >= 0)
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;
}
9 changes: 9 additions & 0 deletions xmake/core/base/os.lua
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ os._getenvs = os._getenvs or os.getenvs
os._cpuinfo = os._cpuinfo or os.cpuinfo
os._meminfo = os._meminfo or os.meminfo
os._readlink = os._readlink or os.readlink
os._signal = os._signal or os.signal

-- syserror code
os.SYSERR_UNKNOWN = -1
Expand All @@ -53,6 +54,9 @@ os.SYSERR_NOT_PERM = 1
os.SYSERR_NOT_FILEDIR = 2
os.SYSERR_NOT_ACCESS = 3

-- signal code
os.SIGINT = 1

-- copy single file or directory
function os._cp(src, dst, rootdir, opt)
opt = opt or {}
Expand Down Expand Up @@ -1415,6 +1419,11 @@ function os.readlink(symlink)
return os._readlink(path.absolute(symlink))
end

-- register signal handler
function os.signal(signo, handler)
os._signal(signo, handler)
end

-- get the program directory
function os.programdir()
return xmake._PROGRAM_DIR
Expand Down
4 changes: 4 additions & 0 deletions xmake/core/sandbox/modules/os.lua
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ sandbox_os.projectdir = os.projectdir
sandbox_os.projectfile = os.projectfile
sandbox_os.getwinsize = os.getwinsize
sandbox_os.getpid = os.getpid
sandbox_os.signal = os.signal

-- syserror code
sandbox_os.SYSERR_UNKNOWN = os.SYSERR_UNKNOWN
Expand All @@ -90,6 +91,9 @@ sandbox_os.SYSERR_NOT_PERM = os.SYSERR_NOT_PERM
sandbox_os.SYSERR_NOT_FILEDIR = os.SYSERR_NOT_FILEDIR
sandbox_os.SYSERR_NOT_ACCESS = os.SYSERR_NOT_ACCESS

-- signal code
sandbox_os.SIGINT = os.SIGINT

-- copy file or directory
function sandbox_os.cp(srcpath, dstpath, opt)
assert(srcpath and dstpath)
Expand Down

0 comments on commit 1520125

Please sign in to comment.