5e: added note support

added wstat / fwstat / alarm
aiju 2011-06-25 16:17:20 +02:00
parent b4ae96bcb9
commit 0b22dfd1f6
7 changed files with 188 additions and 13 deletions

View File

@ -67,6 +67,19 @@ suicide(char *fmt, ...)
abort();
}
int
notehandler(void *, char *note)
{
if(strncmp(note, "sys:", 4) == 0)
return 0;
if(strncmp(note, "emu:", 4) == 0)
exits(note);
addnote(note);
return 1;
}
void
main(int argc, char **argv)
{
@ -90,9 +103,14 @@ main(int argc, char **argv)
initproc();
if(loadtext(argv[0], argc, argv) < 0)
sysfatal("%r");
atnotify(notehandler, 1);
for(;;) {
if(ultraverbose)
dump();
step();
while((P->notein - P->noteout) % NNOTE) {
donote(P->notes[P->noteout % NNOTE], 0);
ainc(&P->noteout);
}
}
}

View File

@ -5,10 +5,8 @@ typedef struct Fd Fd;
enum {
STACKSIZE = 0x100000,
NAMEMAX = 27,
FDBLOCK = 16,
NNOTE = 5,
SEGNUM = 8,
flN = 1<<31,
@ -26,15 +24,24 @@ enum {
};
struct Process {
Segment *S[SEGNUM];
Process *prev, *next; /* linked list (for fs) */
int pid;
char name[NAMEMAX+1]; /* name for status file */
Ref *path; /* Ref + string data */
Segment *S[SEGNUM]; /* memory */
u32int R[16]; /* general purpose registers / PC (R15) */
u32int CPSR; /* status register */
char errbuf[ERRMAX];
char name[NAMEMAX+1];
Ref *path; /* Ref + string data */
Fd *fd;
int pid;
Process *prev, *next;
Fd *fd; /* bitmap of OCEXEC files */
/* note handling */
u32int notehandler;
int innote;
jmp_buf notejmp;
char notes[ERRMAX][NNOTE];
long notein, noteout;
};
extern void **_privates;
@ -69,4 +76,3 @@ struct Fd {
#define havesymbols 0
#define ultraverbose 0
#define systrace 0

View File

@ -27,3 +27,6 @@ void fdclear(Fd *);
void addproc(Process *);
void remproc(Process *);
Process *findproc(int);
void donote(char *, ulong);
void addnote(char *);
void dump(void);

View File

@ -181,6 +181,7 @@ loadtext(char *file, int argc, char **argv)
return -1;
}
copyname(file);
P->notehandler = P->innote = P->notein = P->noteout = 0;
freesegs();
memset(P->R, 0, sizeof(P->R));
P->CPSR = 0;
@ -315,3 +316,66 @@ fdclear(Fd *fd)
fd->fds = nil;
wunlock(fd);
}
/* call this from a notehandler if you don't want the front to fall off */
void
addnote(char *msg)
{
int new;
new = P->notein + 1;
if((new - P->noteout) % NNOTE == 0)
return;
strncpy(P->notes[P->notein % NNOTE], msg, ERRMAX - 1);
P->notein = new;
}
/* the following code is not for the weak of heart */
void
donote(char *msg, ulong type)
{
int rc;
u32int *ureg, *sp, uregp, msgp;
char *msgb;
if(P->notehandler == 0)
exits(msg);
uregp = P->R[13] - 18 * 4;
ureg = vaddrnol(uregp, 18 * 4);
memcpy(ureg, P->R, 15 * 4);
ureg[15] = type;
ureg[16] = P->CPSR;
ureg[17] = P->R[15];
P->R[13] = uregp;
msgp = P->R[13] -= strlen(msg) + 1;
msgb = vaddrnol(msgp, strlen(msg) + 1);
strcpy(msgb, msg);
P->R[13] -= 3 * 4;
sp = vaddrnol(P->R[13], 3 * 4);
sp[0] = 0;
sp[2] = msgp;
P->R[0] = uregp;
P->R[15] = P->notehandler;
P->innote = 1;
switch(rc = setjmp(P->notejmp) - 1) {
case -1:
for(;;) {
if(ultraverbose)
dump();
step();
}
case NDFLT:
exits(msg);
case NCONT:
break;
default:
sysfatal("unhandled noted argument %d", rc);
}
P->innote = 0;
ureg = vaddrnol(uregp, 18 * 4); /* just to be sure */
memcpy(P->R, ureg, 15 * 4);
P->CPSR = ureg[16];
P->R[15] = ureg[17];
}

View File

@ -94,6 +94,7 @@ copyifnec(u32int addr, int len, int *copied)
if(len < 0)
len = strlen(targ) + 1;
ret = emalloc(len);
setmalloctag(ret, getcallerpc(&addr));
memcpy(ret, targ, len);
segunlock(seg);
*copied = 1;
@ -103,7 +104,7 @@ copyifnec(u32int addr, int len, int *copied)
void *
bufifnec(u32int addr, int len, int *buffered)
{
void *targ;
void *targ, *v;
Segment *seg;
targ = vaddr(addr, len, &seg);
@ -113,7 +114,9 @@ bufifnec(u32int addr, int len, int *buffered)
}
segunlock(seg);
*buffered = 1;
return emalloc(len);
v = emalloc(len);
setmalloctag(v, getcallerpc(&addr));
return v;
}
void
@ -122,8 +125,10 @@ copyback(u32int addr, int len, void *data)
void *targ;
Segment *seg;
if(len <= 0)
if(len <= 0) {
free(data);
return;
}
targ = vaddr(addr, len, &seg);
memmove(targ, data, len);
segunlock(seg);

View File

@ -196,6 +196,46 @@ sysfstat(void)
copyback(edir, P->R[0], edirt);
}
static void
syswstat(void)
{
u32int name, edir, nedir;
char *namet;
void *edirt;
int copied, copied2;
name = arg(0);
namet = copyifnec(name, -1, &copied);
edir = arg(1);
nedir = arg(2);
edirt = copyifnec(edir, nedir, &copied2);
if(systrace)
fprint(2, "wstat(%#ux=\"%s\", %#ux, %ud)\n", name, namet, edir, nedir);
P->R[0] = noteerr(wstat(namet, edirt, nedir), nedir);
if(copied)
free(namet);
if(copied2)
free(edirt);
}
static void
sysfwstat(void)
{
u32int fd, edir, nedir;
void *edirt;
int copied;
fd = arg(0);
edir = arg(1);
nedir = arg(2);
edirt = copyifnec(edir, nedir, &copied);
if(systrace)
fprint(2, "fwstat(%d, %#ux, %d)\n", fd, edir, nedir);
P->R[0] = noteerr(fwstat(fd, edirt, nedir), nedir);
if(copied)
free(edirt);
}
static void
sysexits(void)
{
@ -266,6 +306,27 @@ syschdir(void)
static void
sysnotify(void)
{
u32int handler;
handler = arg(0);
if(systrace)
fprint(2, "notify(%#ux)\n", handler);
P->notehandler = handler;
P->R[0] = 0;
}
static void
sysnoted(void)
{
u32int v;
v = arg(0);
if(systrace)
fprint(2, "noted(%d)\n", v);
if(P->innote)
longjmp(P->notejmp, v + 1);
cherrstr("the front fell off");
P->R[0] = -1;
}
static void
@ -541,6 +602,17 @@ sysremove(void)
free(filet);
}
static void
sysalarm(void)
{
u32int msec;
msec = arg(0);
if(systrace)
fprint(2, "alarm(%d)\n", msec);
P->R[0] = alarm(msec);
}
void
syscall(void)
{
@ -556,10 +628,13 @@ syscall(void)
[ERRSTR] syserrstr,
[STAT] sysstat,
[FSTAT] sysfstat,
[WSTAT] syswstat,
[FWSTAT] sysfwstat,
[SEEK] sysseek,
[CHDIR] syschdir,
[FD2PATH] sysfd2path,
[NOTIFY] sysnotify,
[NOTED] sysnoted,
[RFORK] sysrfork,
[EXEC] sysexec,
[AWAIT] sysawait,
@ -571,6 +646,7 @@ syscall(void)
[DUP] sysdup,
[MOUNT] sysmount,
[REMOVE] sysremove,
[ALARM] sysalarm,
};
n = P->R[0];

View File

@ -12,6 +12,7 @@ emalloc(u32int size)
v = malloc(size);
if(v == nil)
sysfatal("%r");
setmalloctag(v, getcallerpc(&size));
return v;
}
@ -22,6 +23,7 @@ emallocz(u32int size)
v = emalloc(size);
memset(v, 0, size);
setmalloctag(v, getcallerpc(&size));
return v;
}
@ -33,5 +35,6 @@ erealloc(void *old, u32int size)
v = realloc(old, size);
if(v == nil)
sysfatal("%r");
setrealloctag(v, getcallerpc(&old));
return v;
}