M gnot/chan.c => gnot/chan.c +1 -0
@@ 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;
M gnot/dat.h => gnot/dat.h +1 -0
@@ 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
M gnot/devsrv.c => gnot/devsrv.c +72 -62
@@ 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;
M gnot/errno.h => gnot/errno.h +1 -0
@@ 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 */
};
M gnot/fault.c => gnot/fault.c +3 -1
@@ 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:
M gnot/fns.h => gnot/fns.h +2 -0
@@ 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);
M gnot/main.c => gnot/main.c +2 -0
@@ 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;
}
M gnot/pgrp.c => gnot/pgrp.c +3 -0
@@ 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; i<p->nmtab; 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;
M gnot/proc.c => gnot/proc.c +8 -3
@@ 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);
M gnot/stream.c => gnot/stream.c +4 -0
@@ 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);
M gnot/trap.c => gnot/trap.c +3 -3
@@ 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))
M port/devproc.c => port/devproc.c +39 -4
@@ 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<<PIDSHIFT)|((pg->index+1)<<QSHIFT);
+ break;
+
case Qdir:
case Qmem:
case Qproc:
case Qstatus:
- if(omode!=OREAD)
+ if(omode != OREAD)
error(0, Eperm);
break;
default:
@@ 264,7 277,7 @@ procread(Chan *c, void *va, long n)
}
/* u area */
- if(c->offset>=USERADDR && c->offset<=USERADDR+BY2PG){
+ if(c->offset>=USERADDR && c->offset<USERADDR+BY2PG){
if(c->offset+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->offset<UNCACHED+conf.npage0*BY2PG){
+ }else if(c->offset>=UNCACHED && c->offset<UNCACHED+conf.npage0*BY2PG){
+ /* BUT mips only TAKE IT OUT */
if(c->offset+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()){
M port/devsrv.c => port/devsrv.c +72 -62
@@ 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;
M port/fault.c => port/fault.c +4 -2
@@ 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);
}
}
M port/pgrp.c => port/pgrp.c +44 -1
@@ 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; i<conf.npgrp; i++,p++){
+ p->index = i;
p->next = p+1;
p->mtab = ialloc(conf.nmtab*sizeof(Mtab), 0);
p->etab = ialloc(conf.npgenv*sizeof(Envp*), 0);
@@ 43,6 46,43 @@ pgrpinit(void)
}
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; i<conf.nproc; i++, p++){
+ if(p->pgrp == 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)
{
Pgrp *p;
@@ 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; i<p->nmtab; 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);
}
}
M power/dat.h => power/dat.h +3 -0
@@ 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;
};
M power/devhotrod.c => power/devhotrod.c +2 -0
@@ 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)
M power/fns.h => power/fns.h +2 -0
@@ 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);
M power/trap.c => power/trap.c +4 -4
@@ 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))