Implement shell builtins: cd, exec, umask (issue #15)
Add builtin dispatch in lcmd.c that checks __builtins table before fork(), so cd/exec/umask operate on the shell process itself.
This commit is contained in:
38
lcmd.c
38
lcmd.c
@@ -20,6 +20,7 @@
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
#include "lcmd.h"
|
||||
#include "lbuiltin.h"
|
||||
|
||||
|
||||
/* ===== argv parser ===== */
|
||||
@@ -555,6 +556,30 @@ static int exec_pipeline (lua_State *L, char **stages, int nstages,
|
||||
}
|
||||
|
||||
|
||||
/* ===== builtin dispatch ===== */
|
||||
|
||||
/*
|
||||
** Check if argv[0] is a shell builtin. If so, call it and push the
|
||||
** result table. Returns 1 if handled, 0 if not a builtin.
|
||||
*/
|
||||
static int try_builtin (lua_State *L, ParsedArgs *pa) {
|
||||
int i;
|
||||
if (lua_getglobal(L, "__builtins") != LUA_TTABLE) {
|
||||
lua_pop(L, 1);
|
||||
return 0;
|
||||
}
|
||||
if (lua_getfield(L, -1, pa->argv[0]) != LUA_TFUNCTION) {
|
||||
lua_pop(L, 2);
|
||||
return 0;
|
||||
}
|
||||
lua_remove(L, -2); /* remove __builtins, keep function */
|
||||
for (i = 0; i < pa->argc; i++)
|
||||
lua_pushstring(L, pa->argv[i]);
|
||||
lua_call(L, pa->argc, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* ===== luaB_command ===== */
|
||||
|
||||
int luaB_command (lua_State *L) {
|
||||
@@ -599,6 +624,12 @@ int luaB_command (lua_State *L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* check for shell builtin */
|
||||
if (try_builtin(L, &pa)) {
|
||||
free_argv(&pa);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* create pipes */
|
||||
if (pipe(out_pipe) != 0) {
|
||||
free_argv(&pa);
|
||||
@@ -731,6 +762,13 @@ int luaB_interactive (lua_State *L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* check for shell builtin */
|
||||
if (try_builtin(L, &pa)) {
|
||||
free_argv(&pa);
|
||||
lua_setglobal(L, "_");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ignore SIGINT, SIGQUIT, SIGPIPE in parent */
|
||||
memset(&sa_new, 0, sizeof(sa_new));
|
||||
sa_new.sa_handler = SIG_IGN;
|
||||
|
||||
Reference in New Issue
Block a user