ref: 0b22dfd1f69985aabc5af37dca8a217a1e6e54e9
parent: b4ae96bcb95e76293a81241bf6edebf27cab7e35
author: aiju <[email protected]>
date: Sat Jun 25 12:17:20 EDT 2011
5e: added note support added wstat / fwstat / alarm
--- a/sys/src/cmd/5e/5e.c
+++ b/sys/src/cmd/5e/5e.c
@@ -67,6 +67,19 @@
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 @@
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);
+ }
}
}
--- a/sys/src/cmd/5e/dat.h
+++ b/sys/src/cmd/5e/dat.h
@@ -5,10 +5,8 @@
enum {
STACKSIZE = 0x100000,
-
NAMEMAX = 27,
-
- FDBLOCK = 16,
+ NNOTE = 5,
SEGNUM = 8,
flN = 1<<31,
@@ -26,15 +24,24 @@
};
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 @@
#define havesymbols 0
#define ultraverbose 0
#define systrace 0
-
--- a/sys/src/cmd/5e/fns.h
+++ b/sys/src/cmd/5e/fns.h
@@ -27,3 +27,6 @@
void addproc(Process *);
void remproc(Process *);
Process *findproc(int);
+void donote(char *, ulong);
+void addnote(char *);
+void dump(void);
--- a/sys/src/cmd/5e/proc.c
+++ b/sys/src/cmd/5e/proc.c
@@ -181,6 +181,7 @@
return -1;
}
copyname(file);
+ P->notehandler = P->innote = P->notein = P->noteout = 0;
freesegs();
memset(P->R, 0, sizeof(P->R));
P->CPSR = 0;
@@ -314,4 +315,67 @@
fd->nfds = 0;
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];
}
--- a/sys/src/cmd/5e/seg.c
+++ b/sys/src/cmd/5e/seg.c
@@ -94,6 +94,7 @@
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 @@
void *
bufifnec(u32int addr, int len, int *buffered)
{
- void *targ;
+ void *targ, *v;
Segment *seg;
targ = vaddr(addr, len, &seg);
@@ -113,7 +114,9 @@
}
segunlock(seg);
*buffered = 1;
- return emalloc(len);
+ v = emalloc(len);
+ setmalloctag(v, getcallerpc(&addr));
+ return v;
}
void
@@ -122,8 +125,10 @@
void *targ;
Segment *seg;
- if(len <= 0)
+ if(len <= 0) {
+ free(data);
return;
+ }
targ = vaddr(addr, len, &seg);
memmove(targ, data, len);
segunlock(seg);
--- a/sys/src/cmd/5e/sys.c
+++ b/sys/src/cmd/5e/sys.c
@@ -197,6 +197,46 @@
}
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)
{
if(arg(0) == 0)
@@ -266,9 +306,30 @@
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
sysrfork(void)
{
u32int flags;
@@ -541,6 +602,17 @@
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 @@
[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 @@
[DUP] sysdup,
[MOUNT] sysmount,
[REMOVE] sysremove,
+ [ALARM] sysalarm,
};
n = P->R[0];
--- a/sys/src/cmd/5e/util.c
+++ b/sys/src/cmd/5e/util.c
@@ -12,6 +12,7 @@
v = malloc(size);
if(v == nil)
sysfatal("%r");
+ setmalloctag(v, getcallerpc(&size));
return v;
}
@@ -22,6 +23,7 @@
v = emalloc(size);
memset(v, 0, size);
+ setmalloctag(v, getcallerpc(&size));
return v;
}
@@ -33,5 +35,6 @@
v = realloc(old, size);
if(v == nil)
sysfatal("%r");
+ setrealloctag(v, getcallerpc(&old));
return v;
}