Bootstrap

sys.fork_exec和os.excute实现的差异

函数sys.fork_exec和os.excute实现的差异
os.excute是lua os库中实现的函数
/lua/src/src/loslib.c
static const luaL_Reg syslib[] = {
236 {“clock”, os_clock},
237 {“date”, os_date},
238 {“difftime”, os_difftime},
239 {“execute”, os_execute},
240 {“exit”, os_exit},
241 {“getenv”, os_getenv},
242 {“remove”, os_remove},
243 {“rename”, os_rename},
244 {“setlocale”, os_setlocale},
245 {“time”, os_time},
246 {“tmpname”, os_tmpname},
247 {NULL, NULL}
248 };

static int os_execute (lua_State *L) {
lua_pushinteger(L, system(luaL_optstring(L, 1, NULL)));
return 1;
}

sys.fork_exec 在luci中实现,定义在/luci/src/libs/sys/luasrc/sys.lua中
58 — Fork to execute a given shell command
59 – @class function
60 – @name fork_exec
61 – @param … Command to call
62 – @return pid of child process
63 function fork_exec(…)
64 local pid = nixio.fork()
65 if pid == 0 then
66 nixio.chdir("/")
67 – change to root dir
68 nixio.chdir("/")
69
70 – patch stdin, out, err to /dev/null
71 local null = nixio.open("/dev/null", “w+”)
72 if null then
73 nixio.dup(null, nixio.stderr)
74 nixio.dup(null, nixio.stdout)
75 nixio.dup(null, nixio.stdin)
76 if null:fileno() > 2 then
77 null:close()
78 end
79 end
80
81 – replace with target command
82 return nixio.exec("/bin/sh", “-c”, …)
83 else
84 return pid
85 end
86 end

nixio库源码在/luci/src/libs/nixio/src,其中process.c定义了进程创建函数
417 static const luaL_reg R[] = {
418 #ifdef linux
419 {“sysinfo”, nixio_sysinfo},
420 #endif
421 #ifndef WINNT
422 {“fork”, nixio_fork},

112 static int nixio_fork(lua_State *L) {
113 pid_t pid = fork();
114 if (pid == -1) {
115 return nixio__perror(L);
116 } else {
117 lua_pushinteger(L, pid);
118 return 1;
119 }
120 }

int nixio__exec(lua_State *L, int m) {
33 const char *path = luaL_checkstring(L, 1);
34 const char *arg;
35 int argn, i;
36
37 if (m == NIXIO_EXECVE) {
38 luaL_checktype(L, 2, LUA_TTABLE);
39 argn = lua_objlen(L, 2) + 1;
40 } else {
41 argn = lua_gettop(L);
42 }
43
44 char *args = lua_newuserdata(L, sizeof(char) * (argn + 1));
45 args[argn] = NULL;
46 args[0] = (char *)path;
47
48 if (m == NIXIO_EXECVE) {
49 for (i = 1; i < argn; i++) {
50 lua_rawgeti(L, 2, i);
51 arg = lua_tostring(L, -1);
52 luaL_argcheck(L, arg, 2, “invalid argument”);
53 args[i] = (char *)arg;
54 }
55
56 if (lua_isnoneornil(L, 3)) {
57 execv(path, args);
58 } else {
59 luaL_checktype(L, 3, LUA_TTABLE);
60 argn = 0;
61 lua_pushnil(L);
62 while (lua_next(L, 3)) {
63 if (!lua_checkstack(L, 1)) {
64 lua_settop(L, 0);
65 return luaL_error(L, “stack overflow”);
66 }
67
68 if (lua_type(L, -2) != LUA_TSTRING || !lua_isstring(L, -1)) {
69 return luaL_argerror(L, 3, “invalid environment”);
70 }
71
72 lua_pushfstring(L, “%s=%s”,
73 lua_tostring(L, -2), lua_tostring(L, -1));
74
75 lua_insert(L, 5);
76 lua_pop(L, 1);
77 argn++;
78 }
79
80 char *env = lua_newuserdata(L, sizeof(char) * (argn + 1));
81 env[argn] = NULL;
82
83 for (i = 1; i <= argn; i++) {
84 env[i-1] = (char *)lua_tostring(L, -(i+1));
85 }
86
87 execve(path, args, env);
88 }
89 } else {
90 for (i = 2; i <= argn; i++) {
91 arg = luaL_checkstring(L, i);
92 args[i-1] = (char *)arg;
93 }
94
95 if (m == NIXIO_EXECV) {
96 execv(path, args);
97 } else {
98 execvp(path, args);
99 }
100 }
101
102 return nixio__perror(L);
103 }

;