summaryrefslogtreecommitdiff
path: root/core/src/xmake/process
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/xmake/process
parent3edf63549fd45db761e09452b9b1af2ce23ee751 (diff)
add subprocess
Diffstat (limited to 'core/src/xmake/process')
-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
7 files changed, 243 insertions, 51 deletions
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);