summaryrefslogtreecommitdiff
path: root/core/src
diff options
context:
space:
mode:
authorruki <[email protected]>2019-08-17 00:49:06 +0800
committerruki <[email protected]>2019-08-16 22:54:38 +0800
commit1de49ce846981a065ce3bea73591b797718ae993 (patch)
tree30f6332a3b94e112f7e8ef7e0c9d38e72e5dde81 /core/src
parent3edf63549fd45db761e09452b9b1af2ce23ee751 (diff)
add subprocess
Diffstat (limited to 'core/src')
m---------core/src/tbox/tbox0
-rw-r--r--core/src/xmake/machine.c35
-rw-r--r--core/src/xmake/makefile5
-rw-r--r--core/src/xmake/process/open.c22
-rw-r--r--core/src/xmake/process/openv.c25
-rw-r--r--core/src/xmake/process/prefix.h80
-rw-r--r--core/src/xmake/process/subprocess___tostring.c (renamed from core/src/xmake/process/close.c)35
-rw-r--r--core/src/xmake/process/subprocess_close___gc.c88
-rw-r--r--core/src/xmake/process/subprocess_wait.c (renamed from core/src/xmake/process/wait.c)27
-rw-r--r--core/src/xmake/process/waitlist.c17
10 files changed, 271 insertions, 63 deletions
diff --git a/core/src/tbox/tbox b/core/src/tbox/tbox
-Subproject 6df2a6b41f964e31ebdae5be49e3fb3ec2740fb
+Subproject 0cdb41ee2f944466e4d69219922f2feb5b76151
diff --git a/core/src/xmake/machine.c b/core/src/xmake/machine.c
index 5e34d8fd5..84c286b09 100644
--- a/core/src/xmake/machine.c
+++ b/core/src/xmake/machine.c
@@ -94,7 +94,7 @@ tb_int_t xm_io_std(lua_State* lua);
tb_int_t xm_io_open(lua_State* lua);
tb_int_t xm_io_openlock(lua_State* lua);
-// the file functions
+// the io/file functions
tb_int_t xm_io_file_read(lua_State* lua);
tb_int_t xm_io_file_seek(lua_State* lua);
tb_int_t xm_io_file_write(lua_State* lua);
@@ -106,7 +106,7 @@ tb_int_t xm_io_file___len(lua_State* lua);
tb_int_t xm_io_file___tostring(lua_State* lua);
tb_int_t xm_io_file___gc(lua_State* lua);
-// the filelock functions
+// the io/filelock functions
tb_int_t xm_io_filelock_path(lua_State* lua);
tb_int_t xm_io_filelock_lock(lua_State* lua);
tb_int_t xm_io_filelock_unlock(lua_State* lua);
@@ -146,9 +146,13 @@ tb_int_t xm_string_startswith(lua_State* lua);
// the process functions
tb_int_t xm_process_open(lua_State* lua);
tb_int_t xm_process_openv(lua_State* lua);
-tb_int_t xm_process_wait(lua_State* lua);
tb_int_t xm_process_waitlist(lua_State* lua);
-tb_int_t xm_process_close(lua_State* lua);
+
+// the process/subprocess functions
+tb_int_t xm_process_subprocess_wait(lua_State* lua);
+tb_int_t xm_process_subprocess_close(lua_State* lua);
+tb_int_t xm_process_subprocess___gc(lua_State* lua);
+tb_int_t xm_process_subprocess___tostring(lua_State* lua);
// the sandbox functions
tb_int_t xm_sandbox_interactive(lua_State* lua);
@@ -237,7 +241,7 @@ static luaL_Reg const g_io_functions[] =
, { tb_null, tb_null }
};
-// the file functions
+// the io/file functions
static luaL_Reg const g_io_file_functions[] =
{
{ "read", xm_io_file_read }
@@ -253,7 +257,7 @@ static luaL_Reg const g_io_file_functions[] =
, { tb_null, tb_null }
};
-// the filelock functions
+// the io/filelock functions
static luaL_Reg const g_io_filelock_functions[] =
{
{ "path", xm_io_filelock_path }
@@ -300,12 +304,20 @@ static luaL_Reg const g_process_functions[] =
{
{ "open", xm_process_open }
, { "openv", xm_process_openv }
-, { "wait", xm_process_wait }
, { "waitlist", xm_process_waitlist }
-, { "close", xm_process_close }
, { tb_null, tb_null }
};
+// the process/subprocess functions
+static luaL_Reg const g_process_subprocess_functions[] =
+{
+ { "close", xm_process_subprocess_close }
+, { "wait", xm_process_subprocess_wait }
+, { "__gc", xm_process_subprocess___gc }
+, { "__tostring", xm_process_subprocess___tostring }
+, { tb_null, tb_null }
+};
+
// the sandbox functions
static luaL_Reg const g_sandbox_functions[] =
{
@@ -628,10 +640,10 @@ xm_machine_ref_t xm_machine_init()
// bind io functions
luaL_register(machine->lua, "io", g_io_functions);
- // bind io.file (metatable) functions
+ // bind io._file (metatable) functions
xm_machine_register_metatable(machine, "io", "_file", "io._file*", g_io_file_functions);
- // bind io.filelock (metatable) functions
+ // bind io._filelock (metatable) functions
xm_machine_register_metatable(machine, "io", "_filelock", "io._filelock*", g_io_filelock_functions);
// add stdin, stdout, stderr to io
@@ -649,6 +661,9 @@ xm_machine_ref_t xm_machine_init()
// bind process functions
luaL_register(machine->lua, "process", g_process_functions);
+ // bind process._subprocess (metatable) functions
+ xm_machine_register_metatable(machine, "process", "_subprocess", "process._subprocess*", g_process_subprocess_functions);
+
// bind sandbox functions
luaL_register(machine->lua, "sandbox", g_sandbox_functions);
diff --git a/core/src/xmake/makefile b/core/src/xmake/makefile
index 7f8e5e4c5..af8d469d0 100644
--- a/core/src/xmake/makefile
+++ b/core/src/xmake/makefile
@@ -75,9 +75,10 @@ xmake_C_FILES += \
string/startswith \
process/open \
process/openv \
- process/wait \
process/waitlist \
- process/close \
+ process/subprocess_wait \
+ process/subprocess___tostring \
+ process/subprocess_close___gc \
sandbox/interactive \
semver/parse \
semver/compare \
diff --git a/core/src/xmake/process/open.c b/core/src/xmake/process/open.c
index fad3e8fec..bbb78ad27 100644
--- a/core/src/xmake/process/open.c
+++ b/core/src/xmake/process/open.c
@@ -133,7 +133,27 @@ tb_int_t xm_process_open(lua_State* lua)
// init process
tb_process_ref_t process = (tb_process_ref_t)tb_process_init_cmd(command, &attr);
- if (process) lua_pushlightuserdata(lua, (tb_pointer_t)process);
+ if (process)
+ {
+ // init subprocess
+ xm_subprocess_t* subprocess = xm_subprocess_new(lua);
+ subprocess->process = process;
+ subprocess->is_opened = tb_true;
+
+ // attach subprocess
+ tb_process_priv_set(process, subprocess);
+
+ // save subprocess name
+ tb_size_t name_maxn = tb_arrayn(subprocess->name);
+ tb_strlcpy(subprocess->name, "subprocess: ", name_maxn);
+ if (command_size < name_maxn - tb_arrayn("subprocess: "))
+ tb_strcat(subprocess->name, command);
+ else
+ {
+ tb_strcat(subprocess->name, "...");
+ tb_strcat(subprocess->name, command + (command_size - name_maxn + tb_arrayn("subprocess: ") + tb_arrayn("...")));
+ }
+ }
else lua_pushnil(lua);
return 1;
}
diff --git a/core/src/xmake/process/openv.c b/core/src/xmake/process/openv.c
index 459a56832..0ff26988c 100644
--- a/core/src/xmake/process/openv.c
+++ b/core/src/xmake/process/openv.c
@@ -50,7 +50,8 @@ tb_int_t xm_process_openv(lua_State* lua)
}
// get shellname
- tb_char_t const* shellname = lua_tostring(lua, 1);
+ size_t shellname_size = 0;
+ tb_char_t const* shellname = luaL_checklstring(lua, 1, &shellname_size);
tb_check_return_val(shellname, 0);
// get the arguments count
@@ -175,7 +176,27 @@ tb_int_t xm_process_openv(lua_State* lua)
// init process
tb_process_ref_t process = (tb_process_ref_t)tb_process_init(shellname, argv, &attr);
- if (process) lua_pushlightuserdata(lua, (tb_pointer_t)process);
+ if (process)
+ {
+ // init subprocess
+ xm_subprocess_t* subprocess = xm_subprocess_new(lua);
+ subprocess->process = process;
+ subprocess->is_opened = tb_true;
+
+ // attach subprocess
+ tb_process_priv_set(process, subprocess);
+
+ // save subprocess name
+ tb_size_t name_maxn = tb_arrayn(subprocess->name);
+ tb_strlcpy(subprocess->name, "subprocess: ", name_maxn);
+ if (shellname_size < name_maxn - tb_arrayn("subprocess: "))
+ tb_strcat(subprocess->name, shellname);
+ else
+ {
+ tb_strcat(subprocess->name, "...");
+ tb_strcat(subprocess->name, shellname + (shellname_size - name_maxn + tb_arrayn("subprocess: ") + tb_arrayn("...")));
+ }
+ }
else lua_pushnil(lua);
// exit argv
diff --git a/core/src/xmake/process/prefix.h b/core/src/xmake/process/prefix.h
index becbb93e6..2b0fec706 100644
--- a/core/src/xmake/process/prefix.h
+++ b/core/src/xmake/process/prefix.h
@@ -1,7 +1,7 @@
/*!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 not use this subprocess except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
@@ -15,7 +15,7 @@
* Copyright (C) 2015 - 2019, TBOOX Open Source Group.
*
* @author ruki
- * @file prefix.h
+ * @subprocess prefix.h
*
*/
#ifndef XM_PROCESS_PREFIX_H
@@ -26,6 +26,82 @@
*/
#include "../prefix.h"
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * macross
+ */
+
+// the subprocess udata type
+#define xm_subprocess_udata "process._subprocess*"
+
+// return lock success
+#define xm_subprocess_return_success() do { return 1; } while (0)
+
+// return lock error with reason
+#define xm_subprocess_return_error(lua, subprocess, reason) \
+ do \
+ { \
+ lua_pushnil(lua); \
+ lua_pushfstring(lua, "error: %s (%s)", reason, subprocess->name); \
+ return 2; \
+ } while (0)
+
+// return closed error
+#define xm_subprocess_return_error_closed(lua) \
+ do \
+ { \
+ lua_pushnil(lua); \
+ lua_pushliteral(lua, "error: subprocess has been closed"); \
+ return 2; \
+ } while (0)
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * types
+ */
+
+// the subprocess type
+typedef struct __xm_subprocess_t
+{
+ // the process reference
+ tb_process_ref_t process;
+
+ // is opened?
+ tb_bool_t is_opened;
+
+ // the process name
+ tb_char_t name[32];
+
+} xm_subprocess_t;
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * interfaces
+ */
+static __tb_inline__ xm_subprocess_t* xm_subprocess_new(lua_State* lua)
+{
+ // check
+ tb_assert_and_check_return_val(lua, tb_null);
+
+ // new subprocess
+ xm_subprocess_t* subprocess = (xm_subprocess_t*)lua_newuserdata(lua, sizeof(xm_subprocess_t));
+ tb_assert_and_check_return_val(subprocess, tb_null);
+
+ // init subprocess
+ luaL_getmetatable(lua, xm_subprocess_udata);
+ lua_setmetatable(lua, -2);
+ tb_memset(subprocess, 0, sizeof(xm_subprocess_t));
+ return subprocess;
+}
+
+static __tb_inline__ xm_subprocess_t* xm_subprocess_get(lua_State* lua)
+{
+ // check
+ tb_assert_and_check_return_val(lua, tb_null);
+
+ // get subprocess
+ xm_subprocess_t* subprocess = (xm_subprocess_t*)luaL_checkudata(lua, 1, xm_subprocess_udata);
+ tb_assert(subprocess);
+ return subprocess;
+}
+
#endif
diff --git a/core/src/xmake/process/close.c b/core/src/xmake/process/subprocess___tostring.c
index dc1a465a3..ab93455b0 100644
--- a/core/src/xmake/process/close.c
+++ b/core/src/xmake/process/subprocess___tostring.c
@@ -11,19 +11,19 @@
* 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 - 2019, TBOOX Open Source Group.
*
* @author ruki
- * @file close.c
+ * @file subprocess___tostring.c
*
*/
/* //////////////////////////////////////////////////////////////////////////////////////
* trace
*/
-#define TB_TRACE_MODULE_NAME "process.close"
-#define TB_TRACE_MODULE_DEBUG (0)
+#define TB_TRACE_MODULE_NAME "subprocess___tostring"
+#define TB_TRACE_MODULE_DEBUG (0)
/* //////////////////////////////////////////////////////////////////////////////////////
* includes
@@ -34,26 +34,17 @@
* implementation
*/
-// process.close(p)
-tb_int_t xm_process_close(lua_State* lua)
+/*
+ * tostring(subprocess)
+ */
+tb_int_t xm_process_subprocess___tostring(lua_State* lua)
{
// check
tb_assert_and_check_return_val(lua, 0);
- // is user data?
- if (!lua_isuserdata(lua, 1))
- return 0;
-
- // get the process
- tb_process_ref_t process = (tb_process_ref_t)lua_touserdata(lua, 1);
- tb_check_return_val(process, 0);
-
- // exit process
- tb_process_exit(process);
-
- // save result: ok
- lua_pushboolean(lua, tb_true);
-
- // ok
- return 1;
+ // get subprocess name as string
+ xm_subprocess_t* subprocess = xm_subprocess_get(lua);
+ lua_pushstring(lua, subprocess->name);
+ xm_subprocess_return_success();
}
+
diff --git a/core/src/xmake/process/subprocess_close___gc.c b/core/src/xmake/process/subprocess_close___gc.c
new file mode 100644
index 000000000..30c3f3656
--- /dev/null
+++ b/core/src/xmake/process/subprocess_close___gc.c
@@ -0,0 +1,88 @@
+/*!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 - 2019, TBOOX Open Source Group.
+ *
+ * @author ruki
+ * @file subprocess_close___gc.c
+ *
+ */
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * trace
+ */
+#define TB_TRACE_MODULE_NAME "subprocess_close___gc"
+#define TB_TRACE_MODULE_DEBUG (0)
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * includes
+ */
+#include "prefix.h"
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * implementation
+ */
+
+static tb_int_t xm_subprocess_close_impl(lua_State* lua, tb_bool_t allow_closed_subprocess)
+{
+ // check
+ tb_assert_and_check_return_val(lua, 0);
+
+ // close subprocess
+ xm_subprocess_t* subprocess = xm_subprocess_get(lua);
+ if (!subprocess->is_opened)
+ {
+ if (allow_closed_subprocess)
+ {
+ lua_pushboolean(lua, tb_true);
+ xm_subprocess_return_success();
+ }
+ else xm_subprocess_return_error_closed(lua);
+ }
+
+ // check
+ tb_assert(subprocess->process);
+
+ // close process
+ tb_process_exit(subprocess->process);
+ subprocess->process = tb_null;
+ subprocess->is_opened = tb_false;
+
+ // mark this subprocess as closed
+ tb_strlcpy(subprocess->name, "subprocess: (closed subprocess)", tb_arrayn(subprocess->name));
+
+ // close ok
+ lua_pushboolean(lua, tb_true);
+ xm_subprocess_return_success();
+}
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * interfaces
+ */
+
+/*
+ * subprocess:close()
+ */
+tb_int_t xm_process_subprocess_close(lua_State* lua)
+{
+ return xm_subprocess_close_impl(lua, tb_false);
+}
+
+/*
+ * subprocess:close()
+ */
+tb_int_t xm_process_subprocess___gc(lua_State* lua)
+{
+ return xm_subprocess_close_impl(lua, tb_true);
+}
diff --git a/core/src/xmake/process/wait.c b/core/src/xmake/process/subprocess_wait.c
index b20b81d74..c7cb82377 100644
--- a/core/src/xmake/process/wait.c
+++ b/core/src/xmake/process/subprocess_wait.c
@@ -15,14 +15,14 @@
* Copyright (C) 2015 - 2019, TBOOX Open Source Group.
*
* @author ruki
- * @file wait.c
+ * @file subprocess_wait.c
*
*/
/* //////////////////////////////////////////////////////////////////////////////////////
* trace
*/
-#define TB_TRACE_MODULE_NAME "process.wait"
+#define TB_TRACE_MODULE_NAME "subprocess_wait"
#define TB_TRACE_MODULE_DEBUG (0)
/* //////////////////////////////////////////////////////////////////////////////////////
@@ -34,31 +34,24 @@
* implementation
*/
-// ok, status = process.wait(proc, timeout)
-tb_int_t xm_process_wait(lua_State* lua)
+// ok, status = subprocess:wait(timeout)
+tb_int_t xm_process_subprocess_wait(lua_State* lua)
{
// check
tb_assert_and_check_return_val(lua, 0);
- // is user data?
- if (!lua_isuserdata(lua, 1))
- {
- // error
- lua_pushfstring(lua, "invalid argument type(%s) for process.wait", luaL_typename(lua, 1));
- lua_error(lua);
- return 0;
- }
-
- // get the process
- tb_process_ref_t process = (tb_process_ref_t)lua_touserdata(lua, 1);
- tb_check_return_val(process, 0);
+ // get subprocess
+ xm_subprocess_t* subprocess = xm_subprocess_get(lua);
+ if (!subprocess->is_opened)
+ xm_subprocess_return_error_closed(lua);
+ tb_assert(subprocess->process);
// get the timeout
tb_long_t timeout = (tb_long_t)luaL_checkinteger(lua, 2);
// wait it
tb_long_t status = 0;
- tb_long_t ok = tb_process_wait(process, &status, timeout);
+ tb_long_t ok = tb_process_wait(subprocess->process, &status, timeout);
// save result
lua_pushinteger(lua, ok);
diff --git a/core/src/xmake/process/waitlist.c b/core/src/xmake/process/waitlist.c
index 2254f199f..98015c2d4 100644
--- a/core/src/xmake/process/waitlist.c
+++ b/core/src/xmake/process/waitlist.c
@@ -81,15 +81,15 @@ tb_int_t xm_process_waitlist(lua_State* lua)
lua_pushinteger(lua, i + 1);
lua_gettable(lua, 1);
- // is userdata?
- if (lua_isuserdata(lua, -1))
+ // save this process
+ xm_subprocess_t* subprocess = (xm_subprocess_t*)luaL_checkudata(lua, -1, xm_subprocess_udata);
+ if (subprocess)
{
- // save this process
- processes[i] = (tb_process_ref_t)lua_touserdata(lua, -1);
- if (!processes[i])
+ processes[i] = subprocess->process;
+ if (!subprocess->is_opened || !processes[i])
{
// error
- lua_pushfstring(lua, "process[%d] is null for process.waitlist", i);
+ lua_pushfstring(lua, "process[%d] is null or closed for process.waitlist", i);
lua_error(lua);
}
}
@@ -124,7 +124,10 @@ tb_int_t xm_process_waitlist(lua_State* lua)
{
// save one process info
lua_newtable(lua);
- lua_pushlightuserdata(lua, (tb_pointer_t)infolist[i].process);
+ tb_process_ref_t process = infolist[i].process;
+ if (process)
+ lua_pushlightuserdata(lua, tb_process_priv(process));
+ else lua_pushnil(lua);
lua_rawseti(lua, -2, 1);
lua_pushinteger(lua, infolist[i].index + 1);
lua_rawseti(lua, -2, 2);