From 9f49db2a6bc926f6777d3faf6d4c2facfc8bcacb Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sat, 10 Nov 1990 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1990-11-10 --- gnot/chan.c | 1 + gnot/dat.h | 1 + gnot/devsrv.c | 134 +++++++++++++++++++++++++--------------------- gnot/errno.h | 1 + gnot/fault.c | 4 +- gnot/fns.h | 2 + gnot/main.c | 2 + gnot/pgrp.c | 3 ++ gnot/proc.c | 11 ++-- gnot/stream.c | 4 ++ gnot/trap.c | 6 +-- port/devproc.c | 43 +++++++++++++-- port/devsrv.c | 134 +++++++++++++++++++++++++--------------------- port/fault.c | 6 ++- port/pgrp.c | 45 +++++++++++++++- power/dat.h | 3 ++ power/devhotrod.c | 2 + power/fns.h | 2 + power/trap.c | 8 +-- 19 files changed, 270 insertions(+), 142 deletions(-) diff --git a/gnot/chan.c b/gnot/chan.c index d98f8ee526e64f0d72e1523dc4878489d61289f7..a29af5de0dbb6cefebb9c141dccb4546cb76c394 100644 --- a/gnot/chan.c +++ b/gnot/chan.c @@ -80,6 +80,7 @@ loop: c->flag = 0; c->ref = 1; unlock(&chanalloc); + c->dev = 0; c->offset = 0; c->mnt = 0; c->stream = 0; diff --git a/gnot/dat.h b/gnot/dat.h index da5ac3e9225a860e066756fffbee47626e28a61f..1450b4e184551953f138cd4f6745263e4de5937a 100644 --- a/gnot/dat.h +++ b/gnot/dat.h @@ -152,6 +152,7 @@ struct Conf int nasync; /* number of async protocol modules */ int npipe; /* number of pipes */ int nservice; /* number of services */ + int nfsyschan; /* number of filsys open channels */ }; struct Dev diff --git a/gnot/devsrv.c b/gnot/devsrv.c index 7ad6fe3ea093f4b4262dbf1c7da2eeb608ef5ffc..e0e8dc67ce9fc0094ecde443b7846fe483fe7de0 100644 --- a/gnot/devsrv.c +++ b/gnot/devsrv.c @@ -7,21 +7,22 @@ #include "devtab.h" #include "fcall.h" -void *calloc(unsigned int, unsigned int); +void *calloc(unsigned, unsigned); void free(void *); /* This structure holds the contents of a directory entry. Entries are kept * in a linked list. */ -struct entry { +typedef struct Entry Entry; +struct Entry { Lock; - struct entry *next; /* next entry */ - struct entry **back; /* entry pointer */ - struct entry *parent; /* parent directory */ + Entry *next; /* next entry */ + Entry **back; /* entry pointer */ + Entry *parent; /* parent directory */ Dir dir; /* dir structure */ - union { - Chan *chan; /* if not a subdirectory */ - struct entry *entries; /* directory entries */ + union{ + Chan *chan; /* if not a subdirectory */ + Entry *entries; /* directory entries */ }; }; @@ -35,11 +36,13 @@ srvreset(void) { } -struct entry *srv_alloc(int mode){ - struct entry *e = calloc(1, sizeof(*e)); +Entry * +srvalloc(int mode){ + Entry *e; static Lock qidlock; static nextqid; + e = calloc(1, sizeof(Entry)); e->dir.atime = e->dir.mtime = seconds(); lock(&qidlock); /* for qid allocation */ e->dir.qid = mode | nextqid++; @@ -52,11 +55,11 @@ srvattach(char *spec) { Chan *c; static Lock rootlock; - static struct entry *root; + static Entry *root; lock(&rootlock); - if (root == 0) { - root = srv_alloc(CHDIR); + if(root==0){ + root = srvalloc(CHDIR); root->dir.mode = CHDIR | 0777; } unlock(&rootlock); @@ -77,23 +80,23 @@ srvclone(Chan *c, Chan *nc) int srvwalk(Chan *c, char *name) { - struct entry *dir, *e; + Entry *dir, *e; isdir(c); - if (strcmp(name, ".") == 0) + if(strcmp(name, ".") == 0) return 1; - if ((dir = c->aux) == 0) + if((dir=c->aux) == 0) panic("bad aux pointer in srvwalk"); - if (strcmp(name, "..") == 0) + if(strcmp(name, "..") == 0) e = dir->parent; - else { + else{ lock(dir); - for (e = dir->entries; e != 0; e = e->next) + for(e=dir->entries; e; e=e->next) if (strcmp(name, e->dir.name) == 0) break; unlock(dir); } - if (e == 0) { + if(e==0){ u->error.code = Enonexist; u->error.type = 0; u->error.dev = 0; @@ -107,32 +110,33 @@ srvwalk(Chan *c, char *name) void srvstat(Chan *c, char *db) { - struct entry *e = c->aux; + Entry *e; + e = c->aux; convD2M(&e->dir, db); } Chan * srvopen(Chan *c, int omode) { - struct entry *e; + Entry *e; Chan *f; - if (c->qid & CHDIR) { - if (omode != OREAD) + if(c->qid & CHDIR){ + if(omode != OREAD) error(0, Eisdir); c->mode = omode; c->flag |= COPEN; c->offset = 0; return c; } - if ((e = c->aux) == 0) - panic("bad aux pointer in srvopen"); - if ((f = e->chan) == 0) + if((e=c->aux) == 0) + error(0, Egreg); + if((f=e->chan) == 0) error(0, Eshutdown); - if (omode & OTRUNC) + if(omode & OTRUNC) error(0, Eperm); - if (omode != f->mode && f->mode != ORDWR) + if(omode!=f->mode && f->mode!=ORDWR) error(0, Eperm); close(c); incref(f); @@ -142,25 +146,27 @@ srvopen(Chan *c, int omode) void srvcreate(Chan *c, char *name, int omode, ulong perm) { - struct entry *parent = c->aux, *e; + Entry *parent, *e; + parent = c->aux; isdir(c); lock(parent); - if (waserror()) { + if (waserror()){ unlock(parent); nexterror(); } - for (e = parent->entries; e != 0; e = e->next) - if (strcmp(name, e->dir.name) == 0) + for(e=parent->entries; e; e=e->next) + if(strcmp(name, e->dir.name) == 0) error(0, Einuse); - e = srv_alloc(perm & CHDIR); + e = srvalloc(perm & CHDIR); e->parent = parent; strcpy(e->dir.name, name); e->dir.mode = perm & parent->dir.mode; e->dir.gid = parent->dir.gid; - if ((e->next = parent->entries) != 0) + if(e->next = parent->entries) /* assign = */ e->next->back = &e->next; - *(e->back = &parent->entries) = e; + e->back = &parent->entries; + *e->back = e; parent->dir.mtime = e->dir.mtime; unlock(parent); poperror(); @@ -173,25 +179,25 @@ srvcreate(Chan *c, char *name, int omode, ulong perm) void srvremove(Chan *c) { - struct entry *e = c->aux; + Entry *e; - if (e->parent == 0) + e = c->aux; + if(e->parent == 0) error(0, Eperm); lock(e->parent); - if (waserror()) { + if(waserror()){ unlock(e->parent); nexterror(); } - if (e->dir.mode & CHDIR) { + if(e->dir.mode & CHDIR){ if (e->entries != 0) error(0, Eperm); - } - else { - if (e->chan == 0) + }else{ + if(e->chan == 0) error(0, Eshutdown); close(e->chan); } - if ((*e->back = e->next) != 0) + if(*e->back = e->next) /* assign = */ e->next->back = e->back; unlock(e->parent); poperror(); @@ -213,11 +219,13 @@ srvclose(Chan *c) * to a list of entries in this directory. Count is the size to be * read. */ -int srv_direntry(struct entry *e, char *a, long count){ +int +srvdirentry(Entry *e, char *a, long count){ Dir dir; - int n = 0; + int n; - while (n != count && e != 0) { + n = 0; + while(n!=count && e!=0){ n += convD2M(&e->dir, a + n); e = e->next; } @@ -227,23 +235,24 @@ int srv_direntry(struct entry *e, char *a, long count){ long srvread(Chan *c, void *va, long n) { - struct entry *dir = c->aux, *e; - int offset = c->offset; + Entry *dir, *e; + int offset; + dir = c->aux; + offset = c->offset; isdir(c); - if (n <= 0) + if(n <= 0) return 0; - if ((offset % DIRLEN) != 0 || (n % DIRLEN) != 0) - error(0, Egreg); + if(offset%DIRLEN || n%DIRLEN) + error(0, Ebaddirread); lock(dir); - for (e = dir->entries; e != 0; e = e->next) - if (offset <= 0) { - n = srv_direntry(e, va, n); + for(e=dir->entries; e; e=e->next) + if(offset <= 0){ + n = srvdirentry(e, va, n); unlock(dir); c->offset += n; return n; - } - else + }else offset -= DIRLEN; unlock(dir); return 0; @@ -252,20 +261,21 @@ srvread(Chan *c, void *va, long n) long srvwrite(Chan *c, void *va, long n) { - struct entry *e = c->aux; + Entry *e; int i, fd; char buf[32]; - if (e->dir.mode & CHDIR) + e = c->aux; + if(e->dir.mode & CHDIR) panic("write to directory"); lock(e); - if (waserror()) { + if(waserror()){ unlock(e); nexterror(); } - if (e->chan != 0) + if(e->chan) error(0, Egreg); - if (n >= sizeof buf) + if(n >= sizeof buf) error(0, Egreg); memcpy(buf, va, n); /* so we can NUL-terminate */ buf[n] = 0; diff --git a/gnot/errno.h b/gnot/errno.h index 2c6e33643e83e423d382065afbaf79f765b43bb3..b29b1de2d453888be63c241a74f0ba366b304275 100644 --- a/gnot/errno.h +++ b/gnot/errno.h @@ -58,5 +58,6 @@ enum{ Enovmem, /* virtual memory allocation failed */ Enoasync, /* out of async stream modules */ Enopipe, /* out of pipes */ + Enofilsys, /* out of filsys resources */ Egreg, /* ken hasn't implemented datakit */ }; diff --git a/gnot/fault.c b/gnot/fault.c index 5f23f4c50a805a8dff8d7a15d15780a015c9acb9..ae99c75761d7b27cee00d6e11ae0f8ab883594a3 100644 --- a/gnot/fault.c +++ b/gnot/fault.c @@ -166,6 +166,8 @@ fault(Ureg *ur, FFrame *f) qunlock(o->chan); pg->o = 0; pg->ref--; + if(user) + pexit("Interrupt", 0); goto cant; } o->chan->offset = (addr-o->va) + o->minca; @@ -290,7 +292,7 @@ validaddr(ulong addr, ulong len, int write) if((long)len < 0){ Err: pprint("invalid address in sys call pc %lux sp %lux\n", ((Ureg*)UREGADDR)->pc, ((Ureg*)UREGADDR)->sp); - postnote(u->p, 1, "bad address", NDebug); + postnote(u->p, 1, "sys: bad address", NDebug); error(0, Ebadarg); } Again: diff --git a/gnot/fns.h b/gnot/fns.h index b03dce77bb7b02c38dd9545d126dc747fc5aa3eb..4b9276a78aac6eedcec0d32a53473e2c1e415b55 100644 --- a/gnot/fns.h +++ b/gnot/fns.h @@ -33,6 +33,7 @@ int devno(int, int); Chan *devopen(Chan*, int, Dirtab*, int, Devgen*); void devstat(Chan*, char*, Dirtab*, int, Devgen*); int devwalk(Chan*, char*, Dirtab*, int, Devgen*); +Chan *domount(Chan*); void duartbaud(int); void duartbreak(int); void duartdtr(int); @@ -50,6 +51,7 @@ void fault(Ureg*, FFrame*); void fdclose(int); Chan *fdtochan(int, int); void filsys(Chan*, char*, long); +void filsysinit(void); void firmware(void); void flowctl(Queue*); void flushcpucache(void); diff --git a/gnot/main.c b/gnot/main.c index 85fb44765081a99234e0687da1ad80079a576f08..4aa404fb337568341d66ead3d97f6d84a8e44c97 100644 --- a/gnot/main.c +++ b/gnot/main.c @@ -47,6 +47,7 @@ main(void) chandevreset(); streaminit(); serviceinit(); + filsysinit(); pageinit(); kmapinit(); userinit(); @@ -328,4 +329,5 @@ confinit(void) conf.nasync = 1; conf.npipe = conf.nstream/2; conf.nservice = conf.nproc/5; + conf.nfsyschan = 31 + conf.nchan/20; } diff --git a/gnot/pgrp.c b/gnot/pgrp.c index 9fea02ce5a3c53cb75f7adc17ecbfb93037a517b..353e9b366438285509d594fad044646cf64c26ba 100644 --- a/gnot/pgrp.c +++ b/gnot/pgrp.c @@ -116,6 +116,7 @@ closepgrp(Pgrp *p) Envp *ep; if(decref(p) == 0){ + lock(&p->debug); p->pgrpid = -1; m = p->mtab; for(i=0; inmtab; i++,m++) @@ -130,6 +131,7 @@ closepgrp(Pgrp *p) lock(&pgrpalloc); p->next = pgrpalloc.free; pgrpalloc.free = p; + unlock(&p->debug); unlock(&pgrpalloc); } } @@ -144,6 +146,7 @@ loop: if(m = mountalloc.free){ /* assign = */ mountalloc.free = m->next; m->ref = 1; + m->next = 0; m->mountid = ++mountalloc.mountid; unlock(&mountalloc); return m; diff --git a/gnot/proc.c b/gnot/proc.c index e6043ecad8c58538529867c0fcd85ee6674b5631..6601275c1e0a57155481b675467f43096a765fa6 100644 --- a/gnot/proc.c +++ b/gnot/proc.c @@ -135,7 +135,7 @@ save(Balu *balu) m->fpstate = FPdirty; } if(BALU->cr0 != 0xFFFFFFFF) /* balu busy */ - memcpy(balu, BALU, sizeof *balu); + memcpy(balu, BALU, sizeof(Balu)); else{ balu->cr0 = 0xFFFFFFFF; BALU->cr0 = 0xFFFFFFFF; @@ -699,6 +699,7 @@ Proc * kproc(char *name, void (*func)(void *), void *arg) { Proc *p; + Chan *c; int n; ulong upa; int lastvar; /* used to compute stack address */ @@ -730,8 +731,12 @@ kproc(char *name, void (*func)(void *), void *arg) */ incref(up->dot); for(n=0; n<=up->maxfd; n++) - up->fd[n] = 0; - up->maxfd = 0; + if(func) + up->fd[n] = 0; + else if(c = u->fd[n]) /* assign = */ + incref(c); + if(!func) + up->maxfd = 0; up->p = p; kunmap(k); diff --git a/gnot/stream.c b/gnot/stream.c index 4a7bccc8fb8a4a16a6526a0d47bd52e1bd317d41..0ce324ff2eebf7155a2a261218ab6650441ff08f 100644 --- a/gnot/stream.c +++ b/gnot/stream.c @@ -133,6 +133,10 @@ allocb(ulong size) while(bcp->first == 0){ unlock(bcp); qlock(bcp); + if(waserror()){ + qunlock(bcp); + nexterror(); + } tsleep(&bcp->r, isblock, (void *)bcp, 250); qunlock(bcp); lock(bcp); diff --git a/gnot/trap.c b/gnot/trap.c index 9f7dc7925e7a4ec8d8f97ab260c89a5f42453884..a479a1cd71e15b84734fc28a282c6d8214f97d60 100644 --- a/gnot/trap.c +++ b/gnot/trap.c @@ -91,7 +91,7 @@ trap(Ureg *ur) if(u) u->p->pc = ur->pc; /* BUG */ if(user){ - sprint(buf, "pc=%lux trap: %s", ur->pc, excname(ur->vo)); + sprint(buf, "sys: trap: %s", ur->pc, excname(ur->vo)); postnote(u->p, 1, buf, NDebug); }else{ print("kernel trap vo=0x%ux pc=%lux\n", ur->vo, ur->pc); @@ -271,14 +271,14 @@ syscall(Ureg *aur) if(!waserror()){ if(r0 >= sizeof systab/BY2WD){ pprint("bad sys call number %d pc %lux\n", r0, ((Ureg*)UREGADDR)->pc); - msg = "bad sys call"; + msg = "sys: bad sys call"; Bad: postnote(u->p, 1, msg, NDebug); error(0, Ebadarg); } if(sp & (BY2WD-1)){ pprint("odd sp in sys call pc %lux sp %lux\n", ((Ureg*)UREGADDR)->pc, ((Ureg*)UREGADDR)->sp); - msg = "odd stack"; + msg = "sys: odd stack"; goto Bad; } if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-4*BY2WD)) diff --git a/port/devproc.c b/port/devproc.c index a281aeda1d7182869738b49cddf090758fe21fd0..8aeb84d4e25b7fc1a32ba192830f833b99fdb53e 100644 --- a/port/devproc.c +++ b/port/devproc.c @@ -4,7 +4,9 @@ #include "dat.h" #include "fns.h" #include "errno.h" -#include "io.h" + +/* BUG mips only TAKE IT OUT */ +#include "io.h" #include "devtab.h" @@ -13,6 +15,7 @@ enum{ Qctl, Qmem, Qnote, + Qnotepg, Qproc, Qstatus, Qtext, @@ -22,6 +25,7 @@ Dirtab procdir[]={ "ctl", Qctl, 0, 0600, "mem", Qmem, 0, 0600, "note", Qnote, 0, 0600, + "notepg", Qnotepg, 0, 0200, "proc", Qproc, sizeof(Proc), 0600, "status", Qstatus, NAMELEN+12+6*12, 0600, "text", Qtext, 0, 0600, @@ -109,6 +113,7 @@ Chan * procopen(Chan *c, int omode) { Proc *p; + Pgrp *pg; Orig *o; Chan *tc; @@ -118,6 +123,7 @@ procopen(Chan *c, int omode) goto done; } p = proctab(SLOT(c->qid)); + pg = p->pgrp; if((p->pid&PIDMASK) != PID(c->qid)) Died: error(0, Eprocdied); @@ -147,11 +153,18 @@ procopen(Chan *c, int omode) case Qctl: case Qnote: break; + + case Qnotepg: + if(omode != OWRITE) + error(0, Eperm); + c->pgrpid = (pg->pgrpid<index+1)<offset>=USERADDR && c->offset<=USERADDR+BY2PG){ + if(c->offset>=USERADDR && c->offsetoffset+n > USERADDR+BY2PG) n = USERADDR+BY2PG - c->offset; pg = p->upage; @@ -283,7 +296,8 @@ procread(Chan *c, void *va, long n) n = KZERO+conf.npage0*BY2PG - c->offset; memcpy(a, (char*)c->offset, n); return n; - } else if(c->offset>=UNCACHED && c->offsetoffset>=UNCACHED && c->offsetoffset+n > UNCACHED+conf.npage0*BY2PG) n = UNCACHED+conf.npage0*BY2PG - c->offset; memcpy(a, (char*)c->offset, n); @@ -353,12 +367,33 @@ long procwrite(Chan *c, void *va, long n) { Proc *p; + Pgrp *pg; User *up; KMap *k; char buf[ERRLEN]; if(c->qid & CHDIR) error(0, Eisdir); + + /* + * Special case: don't worry about process, just use remembered group + */ + if(QID(c->qid) == Qnotepg){ + pg = pgrptab(SLOT(c->pgrpid)); + lock(&pg->debug); + if(waserror()){ + unlock(&pg->debug); + nexterror(); + } + if((pg->pgrpid&PIDMASK) != PID(c->pgrpid)){ + unlock(&pg->debug); + goto Died; + } + pgrpnote(pg, va, n, NUser); + unlock(&pg->debug); + return n; + } + p = proctab(SLOT(c->qid)); lock(&p->debug); if(waserror()){ diff --git a/port/devsrv.c b/port/devsrv.c index 7ad6fe3ea093f4b4262dbf1c7da2eeb608ef5ffc..e0e8dc67ce9fc0094ecde443b7846fe483fe7de0 100644 --- a/port/devsrv.c +++ b/port/devsrv.c @@ -7,21 +7,22 @@ #include "devtab.h" #include "fcall.h" -void *calloc(unsigned int, unsigned int); +void *calloc(unsigned, unsigned); void free(void *); /* This structure holds the contents of a directory entry. Entries are kept * in a linked list. */ -struct entry { +typedef struct Entry Entry; +struct Entry { Lock; - struct entry *next; /* next entry */ - struct entry **back; /* entry pointer */ - struct entry *parent; /* parent directory */ + Entry *next; /* next entry */ + Entry **back; /* entry pointer */ + Entry *parent; /* parent directory */ Dir dir; /* dir structure */ - union { - Chan *chan; /* if not a subdirectory */ - struct entry *entries; /* directory entries */ + union{ + Chan *chan; /* if not a subdirectory */ + Entry *entries; /* directory entries */ }; }; @@ -35,11 +36,13 @@ srvreset(void) { } -struct entry *srv_alloc(int mode){ - struct entry *e = calloc(1, sizeof(*e)); +Entry * +srvalloc(int mode){ + Entry *e; static Lock qidlock; static nextqid; + e = calloc(1, sizeof(Entry)); e->dir.atime = e->dir.mtime = seconds(); lock(&qidlock); /* for qid allocation */ e->dir.qid = mode | nextqid++; @@ -52,11 +55,11 @@ srvattach(char *spec) { Chan *c; static Lock rootlock; - static struct entry *root; + static Entry *root; lock(&rootlock); - if (root == 0) { - root = srv_alloc(CHDIR); + if(root==0){ + root = srvalloc(CHDIR); root->dir.mode = CHDIR | 0777; } unlock(&rootlock); @@ -77,23 +80,23 @@ srvclone(Chan *c, Chan *nc) int srvwalk(Chan *c, char *name) { - struct entry *dir, *e; + Entry *dir, *e; isdir(c); - if (strcmp(name, ".") == 0) + if(strcmp(name, ".") == 0) return 1; - if ((dir = c->aux) == 0) + if((dir=c->aux) == 0) panic("bad aux pointer in srvwalk"); - if (strcmp(name, "..") == 0) + if(strcmp(name, "..") == 0) e = dir->parent; - else { + else{ lock(dir); - for (e = dir->entries; e != 0; e = e->next) + for(e=dir->entries; e; e=e->next) if (strcmp(name, e->dir.name) == 0) break; unlock(dir); } - if (e == 0) { + if(e==0){ u->error.code = Enonexist; u->error.type = 0; u->error.dev = 0; @@ -107,32 +110,33 @@ srvwalk(Chan *c, char *name) void srvstat(Chan *c, char *db) { - struct entry *e = c->aux; + Entry *e; + e = c->aux; convD2M(&e->dir, db); } Chan * srvopen(Chan *c, int omode) { - struct entry *e; + Entry *e; Chan *f; - if (c->qid & CHDIR) { - if (omode != OREAD) + if(c->qid & CHDIR){ + if(omode != OREAD) error(0, Eisdir); c->mode = omode; c->flag |= COPEN; c->offset = 0; return c; } - if ((e = c->aux) == 0) - panic("bad aux pointer in srvopen"); - if ((f = e->chan) == 0) + if((e=c->aux) == 0) + error(0, Egreg); + if((f=e->chan) == 0) error(0, Eshutdown); - if (omode & OTRUNC) + if(omode & OTRUNC) error(0, Eperm); - if (omode != f->mode && f->mode != ORDWR) + if(omode!=f->mode && f->mode!=ORDWR) error(0, Eperm); close(c); incref(f); @@ -142,25 +146,27 @@ srvopen(Chan *c, int omode) void srvcreate(Chan *c, char *name, int omode, ulong perm) { - struct entry *parent = c->aux, *e; + Entry *parent, *e; + parent = c->aux; isdir(c); lock(parent); - if (waserror()) { + if (waserror()){ unlock(parent); nexterror(); } - for (e = parent->entries; e != 0; e = e->next) - if (strcmp(name, e->dir.name) == 0) + for(e=parent->entries; e; e=e->next) + if(strcmp(name, e->dir.name) == 0) error(0, Einuse); - e = srv_alloc(perm & CHDIR); + e = srvalloc(perm & CHDIR); e->parent = parent; strcpy(e->dir.name, name); e->dir.mode = perm & parent->dir.mode; e->dir.gid = parent->dir.gid; - if ((e->next = parent->entries) != 0) + if(e->next = parent->entries) /* assign = */ e->next->back = &e->next; - *(e->back = &parent->entries) = e; + e->back = &parent->entries; + *e->back = e; parent->dir.mtime = e->dir.mtime; unlock(parent); poperror(); @@ -173,25 +179,25 @@ srvcreate(Chan *c, char *name, int omode, ulong perm) void srvremove(Chan *c) { - struct entry *e = c->aux; + Entry *e; - if (e->parent == 0) + e = c->aux; + if(e->parent == 0) error(0, Eperm); lock(e->parent); - if (waserror()) { + if(waserror()){ unlock(e->parent); nexterror(); } - if (e->dir.mode & CHDIR) { + if(e->dir.mode & CHDIR){ if (e->entries != 0) error(0, Eperm); - } - else { - if (e->chan == 0) + }else{ + if(e->chan == 0) error(0, Eshutdown); close(e->chan); } - if ((*e->back = e->next) != 0) + if(*e->back = e->next) /* assign = */ e->next->back = e->back; unlock(e->parent); poperror(); @@ -213,11 +219,13 @@ srvclose(Chan *c) * to a list of entries in this directory. Count is the size to be * read. */ -int srv_direntry(struct entry *e, char *a, long count){ +int +srvdirentry(Entry *e, char *a, long count){ Dir dir; - int n = 0; + int n; - while (n != count && e != 0) { + n = 0; + while(n!=count && e!=0){ n += convD2M(&e->dir, a + n); e = e->next; } @@ -227,23 +235,24 @@ int srv_direntry(struct entry *e, char *a, long count){ long srvread(Chan *c, void *va, long n) { - struct entry *dir = c->aux, *e; - int offset = c->offset; + Entry *dir, *e; + int offset; + dir = c->aux; + offset = c->offset; isdir(c); - if (n <= 0) + if(n <= 0) return 0; - if ((offset % DIRLEN) != 0 || (n % DIRLEN) != 0) - error(0, Egreg); + if(offset%DIRLEN || n%DIRLEN) + error(0, Ebaddirread); lock(dir); - for (e = dir->entries; e != 0; e = e->next) - if (offset <= 0) { - n = srv_direntry(e, va, n); + for(e=dir->entries; e; e=e->next) + if(offset <= 0){ + n = srvdirentry(e, va, n); unlock(dir); c->offset += n; return n; - } - else + }else offset -= DIRLEN; unlock(dir); return 0; @@ -252,20 +261,21 @@ srvread(Chan *c, void *va, long n) long srvwrite(Chan *c, void *va, long n) { - struct entry *e = c->aux; + Entry *e; int i, fd; char buf[32]; - if (e->dir.mode & CHDIR) + e = c->aux; + if(e->dir.mode & CHDIR) panic("write to directory"); lock(e); - if (waserror()) { + if(waserror()){ unlock(e); nexterror(); } - if (e->chan != 0) + if(e->chan) error(0, Egreg); - if (n >= sizeof buf) + if(n >= sizeof buf) error(0, Egreg); memcpy(buf, va, n); /* so we can NUL-terminate */ buf[n] = 0; diff --git a/port/fault.c b/port/fault.c index a8954439ab9e95343b41a1e7252d73f2fb637f42..644cea5857402348ba5951eaccdc1c9e8429d1a3 100644 --- a/port/fault.c +++ b/port/fault.c @@ -98,6 +98,8 @@ fault(Ureg *ur, int user, int code) qunlock(o->chan); pg->o = 0; pg->ref--; + if(user) + pexit("Interrupt", 0); goto cant; } o->chan->offset = (addr-o->va) + o->minca; @@ -218,7 +220,7 @@ validaddr(ulong addr, ulong len, int write) if((long)len < 0){ Err: pprint("invalid address in sys call pc %lux sp %lux\n", ((Ureg*)UREGADDR)->pc, ((Ureg*)UREGADDR)->sp); - postnote(u->p, 1, "bad address", NDebug); + postnote(u->p, 1, "sys: bad address", NDebug); error(0, Ebadarg); } Again: @@ -241,7 +243,7 @@ void evenaddr(ulong addr) { if(addr & 3){ - postnote(u->p, 1, "odd address", NDebug); + postnote(u->p, 1, "sys: odd address", NDebug); error(0, Ebadarg); } } diff --git a/port/pgrp.c b/port/pgrp.c index f6bbebed29f1c8a9763cea3ffc076f009056cbcc..353e9b366438285509d594fad044646cf64c26ba 100644 --- a/port/pgrp.c +++ b/port/pgrp.c @@ -7,6 +7,7 @@ struct{ Lock; + Pgrp *arena; Pgrp *free; ulong pgrpid; }pgrpalloc; @@ -24,10 +25,12 @@ pgrpinit(void) Pgrp *p; Mount *m; - pgrpalloc.free = ialloc(conf.npgrp*sizeof(Pgrp), 0); + pgrpalloc.arena = ialloc(conf.npgrp*sizeof(Pgrp), 0); + pgrpalloc.free = pgrpalloc.arena; p = pgrpalloc.free; for(i=0; iindex = i; p->next = p+1; p->mtab = ialloc(conf.nmtab*sizeof(Mtab), 0); p->etab = ialloc(conf.npgenv*sizeof(Envp*), 0); @@ -42,6 +45,43 @@ pgrpinit(void) m->next = 0; } +Pgrp* +pgrptab(int i) +{ + return &pgrpalloc.arena[i]; +} + +void +pgrpnote(Pgrp *pg, char *a, long n, int flag) +{ + int i; + Proc *p; + char buf[ERRLEN]; + + if(n >= ERRLEN-1) + error(0, Etoobig); + if(n>=4 && strncmp(a, "sys:", 4)==0) + error(0, Ebadarg); + memcpy(buf, a, n); + buf[n] = 0; + p = proctab(0); + for(i=0; ipgrp == pg){ + lock(&p->debug); + if(p->pid==0 || p->pgrp!=pg){ + unlock(&p->debug); + continue; + } + if(waserror()){ + unlock(&p->debug); + continue; + } + postnote(p, 0, buf, flag); + unlock(&p->debug); + } + } +} + Pgrp* newpgrp(void) { @@ -76,6 +116,8 @@ closepgrp(Pgrp *p) Envp *ep; if(decref(p) == 0){ + lock(&p->debug); + p->pgrpid = -1; m = p->mtab; for(i=0; inmtab; i++,m++) if(m->c){ @@ -89,6 +131,7 @@ closepgrp(Pgrp *p) lock(&pgrpalloc); p->next = pgrpalloc.free; pgrpalloc.free = p; + unlock(&p->debug); unlock(&pgrpalloc); } } diff --git a/power/dat.h b/power/dat.h index 73a386d2a62e77732e4c050f20112d16060f8aae..6025e00e02b7552c6a4c11623f1a0f4c698fe009 100644 --- a/power/dat.h +++ b/power/dat.h @@ -109,6 +109,7 @@ struct Chan union{ Stream *stream; /* for stream channels */ void *aux; + ulong pgrpid; /* for #p/notepg */ }; Chan *mchan; /* channel to mounted server */ ulong mqid; /* qid of root of mount point */ @@ -273,10 +274,12 @@ struct Pgrp { Ref; /* also used as a lock when mounting */ Pgrp *next; + int index; /* index in pgrp table */ ulong pgrpid; char user[NAMELEN]; int nmtab; /* highest active mount table entry, +1 */ int nenv; /* highest active env table entry, +1 */ + Lock debug; /* single access via devproc.c */ Mtab *mtab; Envp *etab; }; diff --git a/power/devhotrod.c b/power/devhotrod.c index 8230e20101158cd2ebfbd420e1be92ea41bb8c4a..eb53019bf1d9f6926798bcca071332336a2aaa02 100644 --- a/power/devhotrod.c +++ b/power/devhotrod.c @@ -136,6 +136,7 @@ hotrodopen(Chan *c, int omode) Device *dp; Hotrod *hp; +#ifdef asdf /* * Remind hotrod where the print buffer is. The address we store * is the address of the printbuf in VME A32 space. @@ -143,6 +144,7 @@ hotrodopen(Chan *c, int omode) hp = &hotrod[c->dev]; dp = hp->addr; dp->mem[256*1024/sizeof(ulong)] = (((ulong)&hp->pbuf) - KZERO) | (SLAVE<<28); +#endif if(c->qid == CHDIR){ if(omode != OREAD) diff --git a/power/fns.h b/power/fns.h index b15717e9aa24c49086be899cff5c4c3ae366e791..974a5114b4e6e5ebb5c001fd73cf67c7ccae786a 100644 --- a/power/fns.h +++ b/power/fns.h @@ -125,6 +125,8 @@ void panic(char*, ...); void pexit(char*, int); void pgrpcpy(Pgrp*, Pgrp*); void pgrpinit(void); +void pgrpnote(Pgrp*, char*, long, int); +Pgrp *pgrptab(int); int postnote(Proc*, int, char*, int); int pprint(char*, ...); Block *prepend(Block*, int); diff --git a/power/trap.c b/power/trap.c index 578da424a6b0c364f57e908b63ad5a323945158a..9fe1849b5fadd258ceff096aaf903a2570886571 100644 --- a/power/trap.c +++ b/power/trap.c @@ -155,9 +155,9 @@ trap(Ureg *ur) if(user){ spllo(); if(ecode == FPEXC) - sprint(buf, "fp: %s FCR31 %lux", fpexcname(x), x); + sprint(buf, "sys: fp: %s FCR31 %lux", fpexcname(x), x); else - sprint(buf, "trap: %s[%d]", excname[ecode], m->machno); + sprint(buf, "sys: trap: %s[%d]", excname[ecode], m->machno); postnote(u->p, 1, buf, NDebug); }else{ print("%s %s pc=%lux\n", user? "user": "kernel", excname[ecode], ur->pc); @@ -463,14 +463,14 @@ syscall(Ureg *aur) if(!waserror()){ if(r1 >= sizeof systab/BY2WD){ pprint("bad sys call number %d pc %lux\n", r1, ((Ureg*)UREGADDR)->pc); - msg = "bad sys call"; + msg = "sys: bad sys call"; Bad: postnote(u->p, 1, msg, NDebug); error(0, Ebadarg); } if(sp & (BY2WD-1)){ pprint("odd sp in sys call pc %lux sp %lux\n", ((Ureg*)UREGADDR)->pc, ((Ureg*)UREGADDR)->sp); - msg = "odd stack"; + msg = "sys: odd stack"; goto Bad; } if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-4*BY2WD))