#include #include #include #include "runtime.h" #include "interp.h" extern PID_t PID; RtCmd *RTCMDS = NULL; RtAlias *RTALIASES = NULL; #define RTCMD(name, _fn) \ do { \ RtCmd *_cmd = umalloc(sizeof(*_cmd)); \ _cmd->cmdname = (name); \ _cmd->fn = (_fn); \ LL_APPEND(RTCMDS, _cmd); \ } while(0) bool rt_print(Token *tks) { Token *tk, *tktmp; LL_FOREACH_SAFE(tks, tk, tktmp) { uprintf("%s", tk->str); if (tk->next != NULL) { uprintf(" "); } } uprintf("\n"); return true; } bool rt_mkalias(Token *tks) { RtAlias *alias = umalloc(sizeof(*alias)); string_memset(alias, 0, sizeof(*alias)); size_t i; Token *tk, *tktmp; LL_FOREACH_SAFE_IDX(tks, tk, tktmp, i) { if (i == 0) { string_memcpy(alias->namebuf, tk->str, MIN(string_len(tk->str), RTALIAS_NAMEBUF_MAX)); } else if (i == 1) { string_memcpy(alias->valbuf, tk->str, MIN(string_len(tk->str), RTALIAS_VALBUF_MAX)); } } LL_APPEND(RTALIASES, alias); return true; } bool rt_PID(Token *tks) { uprintf("%lu\n", PID); return true; } bool rt_subsh(Token *tks) { bool ok = true; char *prepended_args[] = { "-m", "runstring", "-preload", "base:/scripts/rc.tb", "-rs" }; #define SUBSH_MAX_STRING PROC_ARG_MAX char *s = umalloc(SUBSH_MAX_STRING); string_memset(s, 0, SUBSH_MAX_STRING); size_t cursor = 0; Token *argtk, *argtktmp; LL_FOREACH_SAFE(tks, argtk, argtktmp) { size_t len = string_len(argtk->str); string_memcpy(&s[cursor], argtk->str, len); cursor += len; s[cursor] = ' '; cursor++; } char **args1 = umalloc(sizeof(char *) * (ARRLEN(prepended_args) + 1)); for (size_t i = 0; i < ARRLEN(prepended_args); i++) { args1[i] = umalloc(PROC_ARG_MAX); string_memset(args1[i], 0, PROC_ARG_MAX); string_strcpy(args1[i], prepended_args[i]); } args1[ARRLEN(prepended_args)] = umalloc(PROC_ARG_MAX); string_strcpy(args1[ARRLEN(prepended_args)], s); int32_t app = processctl(-1, PCTL_SPAWN, (uint64_t)"base:/bin/tb", (uint64_t)args1, ARRLEN(prepended_args)+1); if (app < 0) { ok = false; goto done; } StringBuffer outbuf; stringbuffer_init(&outbuf); ipcpipe(PID, 10, IPCPIPE_MAKE, NULL, 0); ipcpipe(app, IPCPIPE_OUT, IPCPIPE_REPLACE, (uint8_t *)PID, 10); processctl(app, PCTL_RUN, 0, 0, 0); while (processctl(app, PCTL_POLLSTATE, 0, 0, 0) != 4) { int32_t r; char buf[100]; string_memset(buf, 0, sizeof(buf)); r = ipcpipe(app, IPCPIPE_OUT, IPCPIPE_READ, (uint8_t *)buf, sizeof(buf)-1); stringbuffer_appendcstr(&outbuf, buf); } ipcpipe(PID, 10, IPCPIPE_DELETE, NULL, 0); stringbuffer_free(&outbuf); done: for (size_t i = 0; i < ARRLEN(prepended_args)+1; i++) { ufree(args1[i]); } ufree(s); return ok; } void rt_init(void) { RTCMD("%print", &rt_print); RTCMD("%mkalias", &rt_mkalias); RTCMD("%PID", &rt_PID); RTCMD("%subsh", &rt_subsh); }