5e: added note support
added wstat / fwstat / alarm
parent
b4ae96bcb9
commit
0b22dfd1f6
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue