ref: a062a0574fa9bbff7f3cb62251b41d42a441440f
dir: /session.c/
#include <u.h>
#include <libc.h>
#include <thread.h>
#include "dat.h"
#include "fns.h"
typedef struct SessionList SessionList;
struct SessionList
{
uvlong count;
Session **sessions;
};
SessionList *sessions;
void
appendlog(Session *s, char *data)
{
uvlong size = strlen(data);
qlock(&s->loglock);
s->logsize += size;
s->log = allocextra(s, s->logsize);
memcpy(&s->log[s->logsize-size], data, size);
s->qlog.vers++;
rwakeupall(&s->logwait);
qunlock(&s->loglock);
}
static void
sessionproc(void *arg)
{
char *prompt = " "; /* 6-space prompt */
char *buf = nil;
Session *s = arg;
while(1){
appendlog(s, prompt);
free(buf);
recv(s->input, &buf);
appendlog(s, buf);
if(strlen(buf) > 0 && buf[0] == ')')
systemcmd(s, buf+1, 0);
else{
if(trap(EAny)){
appendlog(s, errdesc());
appendlog(s, ": ");
appendlog(s, errmsg());
appendlog(s, "\n");
continue;
}
TokenList *tokens = scan(buf);
Ast *ast = parse(tokens, 0);
eval(s, ast);
endtrap();
}
}
}
Session *
allocsession(void)
{
static uvlong id = 1;
Session *s = alloc(DataSession);
s->id = id++;
s->name = smprint("%ulld", s->id);
s->active = 1;
s->logwait.l = &s->loglock;
s->logsize = 0;
s->log = nil;
s->modules = alloc(DataModuleList);
s->input = chancreate(sizeof(char *), 0);
sessions->count++;
sessions->sessions = allocextra(sessions, sizeof(Session *) * sessions->count);
sessions->sessions[sessions->count-1] = s;
proccreate(sessionproc, s, 1024*1024);
return s;
}
Enumeration *
enumsessions(void)
{
Enumeration *e = allocenum(sessions->count);
for(uvlong i = 0; i < sessions->count; i++)
e->items[i] = sessions->sessions[i];
return e;
}
void
initsessions(void)
{
dataspecs[DataSessionList].size = sizeof(SessionList);
sessions = alloc(DataSessionList);
setroot(sessions, 1);
}