Files
my-os-project2/user/tb/runtime.c
2025-10-01 21:26:22 +02:00

177 lines
3.9 KiB
C

#include <stddef.h>
#include <stdbool.h>
#include <ulib.h>
#include "runtime.h"
#include "interp.h"
RtStringV *RTSTRINGV_STACK = NULL;
void rtstringv_stackpushcopy(char *s, size_t len) {
char *c = umalloc(len+1);
string_memcpy(c, s, len);
c[len] = '\0';
RtStringV *v = umalloc(sizeof(*v));
v->data = c;
LL_APPEND(RTSTRINGV_STACK, v);
}
char *rtstringv_stackpop(void) {
RtStringV *v;
LL_BACK(RTSTRINGV_STACK, v);
if (v == NULL) {
return NULL;
}
LL_REMOVE(RTSTRINGV_STACK, v);
char *d = v->data;
ufree(v);
return d;
}
char *rtstringv_stackpeek(void) {
RtStringV *v;
LL_BACK(RTSTRINGV_STACK, v);
if (v == NULL) {
return NULL;
}
return v->data;
}
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(" ");
}
}
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_do(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);
if (r > 0) {
stringbuffer_appendcstr(&outbuf, buf);
}
}
ipcpipe(PID, 10, IPCPIPE_DELETE, NULL, 0);
rtstringv_stackpushcopy(outbuf.data, outbuf.count);
stringbuffer_free(&outbuf);
done:
for (size_t i = 0; i < ARRLEN(prepended_args)+1; i++) {
ufree(args1[i]);
}
ufree(s);
return ok;
}
bool rt_stackpush(Token *tks) {
Token *tk, *tktmp;
LL_FOREACH_SAFE(tks, tk, tktmp) {
rtstringv_stackpushcopy(tk->str, string_len(tk->str));
}
return true;
}
bool rt_stackpop(Token *tks) {
(void)tks;
char *s = rtstringv_stackpop();
if (s) ufree(s);
return true;
}
void rt_init(void) {
RTCMD("%print", &rt_print);
RTCMD("%mkalias", &rt_mkalias);
RTCMD("%PID", &rt_PID);
RTCMD("%do", &rt_do);
RTCMD("%stackpush", &rt_stackpush);
RTCMD("%stackpop", &rt_stackpop);
}