M gnot/dat.h => gnot/dat.h +5 -3
@@ 88,7 88,8 @@ struct Alarm
#define CHEXCL 0x20000000L
struct Chan
{
- QLock; /* general access */
+ QLock rdl; /* read access */
+ QLock wrl; /* write access */
Ref;
union{
Chan *next; /* allocation */
@@ 171,8 172,8 @@ struct Dev
Chan *(*open)(Chan*, int);
void (*create)(Chan*, char*, int, ulong);
void (*close)(Chan*);
- long (*read)(Chan*, void*, long);
- long (*write)(Chan*, void*, long);
+ long (*read)(Chan*, void*, long, ulong);
+ long (*write)(Chan*, void*, long, ulong);
void (*remove)(Chan*);
void (*wstat)(Chan*, char*);
};
@@ 473,6 474,7 @@ struct Stream {
QLock rdlock; /* read lock */
Queue *procq; /* write queue at process end */
Queue *devq; /* read queue at device end */
+ Block *err; /* error message from down stream */
};
#define RD(q) ((q)->other < (q) ? (q->other) : q)
#define WR(q) ((q)->other > (q) ? (q->other) : q)
M gnot/devcons.c => gnot/devcons.c +20 -20
@@ 269,14 269,14 @@ pprint(char *fmt, ...)
return 0;
n = sprint(buf, "%s %d: ", u->p->text, u->p->pid);
n = doprint(buf+n, buf+sizeof(buf), fmt, (&fmt+1)) - buf;
- qlock(c);
+ qlock(&c->wrl);
if(waserror()){
- qunlock(c);
+ qunlock(&c->wrl);
return 0;
}
- (*devtab[c->type].write)(c, buf, n);
+ (*devtab[c->type].write)(c, buf, n, c->offset);
c->offset += n;
- qunlock(c);
+ qunlock(&c->wrl);
poperror();
return n;
}
@@ 554,7 554,7 @@ consclose(Chan *c)
}
long
-consread(Chan *c, void *buf, long n)
+consread(Chan *c, void *buf, long n, ulong offset)
{
int ch, i, j, k;
ulong l;
@@ 622,13 622,13 @@ consread(Chan *c, void *buf, long n)
return streamread(c, buf, n);
case Qrs232ctl:
- if(c->offset)
+ if(offset)
return 0;
*(char *)buf = duartinputport();
return 1;
case Qcputime:
- k = c->offset;
+ k = offset;
if(k >= sizeof tmp)
return 0;
if(k+n > sizeof tmp)
@@ 645,21 645,21 @@ consread(Chan *c, void *buf, long n)
return n;
case Qpgrpid:
- return readnum(c->offset, buf, n, u->p->pgrp->pgrpid, NUMSIZE);
+ return readnum(offset, buf, n, u->p->pgrp->pgrpid, NUMSIZE);
case Qpid:
- return readnum(c->offset, buf, n, u->p->pid, NUMSIZE);
+ return readnum(offset, buf, n, u->p->pid, NUMSIZE);
case Qppid:
- return readnum(c->offset, buf, n, u->p->parentpid, NUMSIZE);
+ return readnum(offset, buf, n, u->p->parentpid, NUMSIZE);
case Qtime:
- return readnum(c->offset, buf, n, boottime+TK2SEC(MACHP(0)->ticks), NUMSIZE);
+ return readnum(offset, buf, n, boottime+TK2SEC(MACHP(0)->ticks), NUMSIZE);
case Qmsec:
- return readnum(c->offset, buf, n, TK2MS(MACHP(0)->ticks), NUMSIZE);
+ return readnum(offset, buf, n, TK2MS(MACHP(0)->ticks), NUMSIZE);
case Qclock:
- k = c->offset;
+ k = offset;
if(k >= 2*NUMSIZE)
return 0;
if(k+n > 2*NUMSIZE)
@@ 670,7 670,7 @@ consread(Chan *c, void *buf, long n)
return n;
case Quser:
- return readstr(c->offset, buf, n, u->p->pgrp->user);
+ return readstr(offset, buf, n, u->p->pgrp->user);
case Qnull:
return 0;
@@ 699,7 699,7 @@ consread(Chan *c, void *buf, long n)
}
long
-conswrite(Chan *c, void *va, long n)
+conswrite(Chan *c, void *va, long n, ulong offset)
{
char cbuf[64];
char buf[256];
@@ 742,12 742,12 @@ conswrite(Chan *c, void *va, long n)
case Quser:
if(u->p->pgrp->user[0]) /* trying to overwrite /dev/user */
error(Eperm);
- if(c->offset >= NAMELEN-1)
+ if(offset >= NAMELEN-1)
return 0;
- if(c->offset+n >= NAMELEN-1)
- n = NAMELEN-1 - c->offset;
- memmove(u->p->pgrp->user+c->offset, a, n);
- u->p->pgrp->user[c->offset+n] = 0;
+ if(offset+n >= NAMELEN-1)
+ n = NAMELEN-1 - offset;
+ memmove(u->p->pgrp->user+offset, a, n);
+ u->p->pgrp->user[offset+n] = 0;
break;
case Qcputime:
M gnot/devincon.c => gnot/devincon.c +2 -2
@@ 393,13 393,13 @@ inconclose(Chan *c)
}
long
-inconread(Chan *c, void *buf, long n)
+inconread(Chan *c, void *buf, long n, ulong offset)
{
return streamread(c, buf, n);
}
long
-inconwrite(Chan *c, void *buf, long n)
+inconwrite(Chan *c, void *buf, long n, ulong offset)
{
return streamwrite(c, buf, n, 0);
}
M gnot/devport.c => gnot/devport.c +6 -6
@@ 106,7 106,7 @@ portclose(Chan *c)
{}
long
-portread(Chan *c, char *a, long n)
+portread(Chan *c, char *a, long n, ulong offset)
{
long s, k;
if (n == 0)
@@ 115,9 115,9 @@ portread(Chan *c, char *a, long n)
case Qdir:
return devdirread(c, a, n, portdir, NPORT, devgen);
case Qdata:
- if (!conf.portispaged || (s = c->offset >> PORTSHIFT) > 0xff)
+ if (!conf.portispaged || (s = offset >> PORTSHIFT) > 0xff)
s = -1;
- k = c->offset % PORTSIZE;
+ k = offset % PORTSIZE;
P_qlock(s);
switch ((int)n) {
case 1:
@@ 139,16 139,16 @@ portread(Chan *c, char *a, long n)
}
long
-portwrite(Chan *c, char *a, long n)
+portwrite(Chan *c, char *a, long n, ulong offset)
{
long s, k;
if (n == 0)
return 0;
switch ((int)c->qid.path) {
case Qdata:
- if (!conf.portispaged || (s = c->offset >> PORTSHIFT) > 0xff)
+ if (!conf.portispaged || (s = offset >> PORTSHIFT) > 0xff)
s = -1;
- k = c->offset % PORTSIZE;
+ k = offset % PORTSIZE;
P_qlock(s);
switch ((int)n) {
case 1:
M gnot/fns.h => gnot/fns.h +1 -1
@@ 197,7 197,7 @@ Stream *streamnew(ushort, ushort, ushort, Qinfo*, int);
void streamopen(Chan*, Qinfo*);
int streamparse(char*, Block*);
void streamstat(Chan*, char*, char*);
-long stringread(Chan*, void*, long, char*);
+long stringread(Chan*, void*, long, char*, ulong);
long syscall(Ureg*);
int tas(char*);
void touser(void);
M gnot/main.c => gnot/main.c +3 -3
@@ 118,13 118,13 @@ init0(void)
u->dot = clone(u->slash, 0);
if(!waserror()){
c = namec("#e/bootline", Acreate, OWRITE, 0600);
- (*devtab[c->type].write)(c, bootline, 64);
+ (*devtab[c->type].write)(c, bootline, 64, 0);
close(c);
c = namec("#e/bootserver", Acreate, OWRITE, 0600);
- (*devtab[c->type].write)(c, bootserver, 64);
+ (*devtab[c->type].write)(c, bootserver, 64, 0);
close(c);
c = namec("#e/bootdevice", Acreate, OWRITE, 0600);
- (*devtab[c->type].write)(c, bootdevice, 2);
+ (*devtab[c->type].write)(c, bootdevice, 2, 0);
close(c);
}
poperror();
M gnot/mem.h => gnot/mem.h +3 -0
@@ 100,3 100,6 @@
#define NSEG 5
#define MACHSIZE 4096
+
+
+#define isphys(p) ((((ulong)(p))&0xF0000000) == KSEG)
M port/dev.c => port/dev.c +6 -0
@@ 107,6 107,12 @@ devwalk(Chan *c, char *name, Dirtab *tab, int ntab, Devgen *gen)
}
}
+int devclwalk(Chan *c, Chan *nc, char *name, Dirtab *tab, int ntab, Devgen *gen)
+{
+ c = devclone(c, nc);
+ return devwalk(c, name, tab, ntab, gen);
+}
+
void
devstat(Chan *c, char *db, Dirtab *tab, int ntab, Devgen *gen)
{
M port/devbit.c => port/devbit.c +4 -4
@@ 275,7 275,7 @@ bitclose(Chan *c)
#define K2U(x) (x)
long
-bitread(Chan *c, void *va, long n)
+bitread(Chan *c, void *va, long n, ulong offset)
{
uchar *p, *q;
long miny, maxy, t, x, y;
@@ 429,7 429,7 @@ bitread(Chan *c, void *va, long n)
error(Ebadblt);
case Qscreen:
- if(c->offset==0){
+ if(offset==0){
if(n < 5*12)
error(Eio);
sprint(va, "%11d %11d %11d %11d %11d ",
@@ 441,7 441,7 @@ bitread(Chan *c, void *va, long n)
}
ws = 1<<(3-gscreen.ldepth); /* pixels per byte */
l = (gscreen.r.max.x+ws-1)/ws - gscreen.r.min.x/ws;
- t = c->offset-5*12;
+ t = offset-5*12;
miny = t/l;
maxy = (t+n)/l;
if(miny >= gscreen.r.max.y)
@@ 467,7 467,7 @@ bitread(Chan *c, void *va, long n)
long
-bitwrite(Chan *c, void *va, long n)
+bitwrite(Chan *c, void *va, long n, ulong offset)
{
uchar *p, *q;
long m, v, miny, maxy, minx, maxx, t, x, y, tw, th;
M port/devboot.c => port/devboot.c +7 -7
@@ 74,7 74,7 @@ bootclose(Chan *c)
}
long
-bootread(Chan *c, void *buf, long n)
+bootread(Chan *c, void *buf, long n, ulong offset)
{
switch(c->qid.path & ~CHDIR){
case Qdir:
@@ 85,21 85,21 @@ bootread(Chan *c, void *buf, long n)
}
long
-bootwrite(Chan *c, void *buf, long n)
+bootwrite(Chan *c, void *buf, long n, ulong offset)
{
ulong pc;
switch(c->qid.path & ~CHDIR){
case Qmem:
/* kernel memory. BUG: shouldn't be so easygoing. BUG: mem mapping? */
- if(c->offset>=KZERO && c->offset<KZERO+conf.npage*BY2PG){
+ if(offset>=KZERO && offset<KZERO+conf.npage*BY2PG){
/* print("%ux, %d\n", c->offset, n);/**/
- if(c->offset+n > KZERO+conf.npage*BY2PG)
- n = KZERO+conf.npage*BY2PG - c->offset;
- memmove((char*)c->offset, buf, n);
+ if(offset+n > KZERO+conf.npage*BY2PG)
+ n = KZERO+conf.npage*BY2PG - offset;
+ memmove((char*)offset, buf, n);
return n;
}
- print("bootwrite: bad addr %lux\n", c->offset);
+ print("bootwrite: bad addr %lux\n", offset);
error(Ebadarg);
case Qboot:
M port/devcons.c => port/devcons.c +18 -18
@@ 197,14 197,14 @@ pprint(char *fmt, ...)
return 0;
n = sprint(buf, "%s %d: ", u->p->text, u->p->pid);
n = doprint(buf+n, buf+sizeof(buf), fmt, (&fmt+1)) - buf;
- qlock(c);
+ qlock(&c->wrl);
if(waserror()){
- qunlock(c);
+ qunlock(&c->wrl);
return 0;
}
- (*devtab[c->type].write)(c, buf, n);
+ (*devtab[c->type].write)(c, buf, n, c->offset);
c->offset += n;
- qunlock(c);
+ qunlock(&c->wrl);
poperror();
return n;
}
@@ 435,7 435,7 @@ consclose(Chan *c)
}
long
-consread(Chan *c, void *buf, long n)
+consread(Chan *c, void *buf, long n, ulong offset)
{
int ch, i, j, k;
ulong l;
@@ 492,7 492,7 @@ consread(Chan *c, void *buf, long n)
return i;
case Qcputime:
- k = c->offset;
+ k = offset;
if(k >= sizeof tmp)
return 0;
if(k+n > sizeof tmp)
@@ 509,22 509,22 @@ consread(Chan *c, void *buf, long n)
return n;
case Qpgrpid:
- return readnum(c->offset, buf, n, u->p->pgrp->pgrpid, NUMSIZE);
+ return readnum(offset, buf, n, u->p->pgrp->pgrpid, NUMSIZE);
case Qpid:
- return readnum(c->offset, buf, n, u->p->pid, NUMSIZE);
+ return readnum(offset, buf, n, u->p->pid, NUMSIZE);
case Qppid:
- return readnum(c->offset, buf, n, u->p->parentpid, NUMSIZE);
+ return readnum(offset, buf, n, u->p->parentpid, NUMSIZE);
case Qtime:
- return readnum(c->offset, buf, n, boottime+TK2SEC(MACHP(0)->ticks), 12);
+ return readnum(offset, buf, n, boottime+TK2SEC(MACHP(0)->ticks), 12);
case Quser:
- return readstr(c->offset, buf, n, u->p->pgrp->user);
+ return readstr(offset, buf, n, u->p->pgrp->user);
case Qlog:
- return readlog(c->offset, buf, n);
+ return readlog(offset, buf, n);
case Qnull:
return 0;
@@ 536,7 536,7 @@ consread(Chan *c, void *buf, long n)
}
long
-conswrite(Chan *c, void *va, long n)
+conswrite(Chan *c, void *va, long n, ulong offset)
{
char cbuf[64];
char buf[256];
@@ 573,12 573,12 @@ conswrite(Chan *c, void *va, long n)
case Quser:
if(u->p->pgrp->user[0]) /* trying to overwrite /dev/user */
error(Eperm);
- if(c->offset >= NAMELEN-1)
+ if(offset >= NAMELEN-1)
return 0;
- if(c->offset+n >= NAMELEN-1)
- n = NAMELEN-1 - c->offset;
- memmove(u->p->pgrp->user+c->offset, a, n);
- u->p->pgrp->user[c->offset+n] = 0;
+ if(offset+n >= NAMELEN-1)
+ n = NAMELEN-1 - offset;
+ memmove(u->p->pgrp->user+offset, a, n);
+ u->p->pgrp->user[offset+n] = 0;
break;
case Qcputime:
M port/devdk.c => port/devdk.c +5 -5
@@ 863,7 863,7 @@ dkclose(Chan *c)
}
long
-dkread(Chan *c, void *a, long n)
+dkread(Chan *c, void *a, long n, ulong offset)
{
Line *lp;
@@ 880,17 880,17 @@ dkread(Chan *c, void *a, long n)
lp = &dk[c->dev].line[STREAMID(c->qid.path)];
switch(STREAMTYPE(c->qid.path)){
case Daddrqid:
- return stringread(c, a, n, lp->addr);
+ return stringread(c, a, n, lp->addr, offset);
case Draddrqid:
- return stringread(c, a, n, lp->raddr);
+ return stringread(c, a, n, lp->raddr, offset);
case Duserqid:
- return stringread(c, a, n, lp->ruser);
+ return stringread(c, a, n, lp->ruser, offset);
}
error(Eperm);
}
long
-dkwrite(Chan *c, void *a, long n)
+dkwrite(Chan *c, void *a, long n, ulong offset)
{
int t;
char buf[256];
M port/devdup.c => port/devdup.c +2 -2
@@ 104,7 104,7 @@ dupclose(Chan *c)
}
long
-dupread(Chan *c, void *va, long n)
+dupread(Chan *c, void *va, long n, ulong offset)
{
char *a = va;
@@ 114,7 114,7 @@ dupread(Chan *c, void *va, long n)
}
long
-dupwrite(Chan *c, void *va, long n)
+dupwrite(Chan *c, void *va, long n, ulong offset)
{
panic("dupwrite");
}
M port/devenv.c => port/devenv.c +9 -9
@@ 435,7 435,7 @@ envpgclose(Env *e)
}
long
-envread(Chan *c, void *va, long n)
+envread(Chan *c, void *va, long n, ulong offset)
{
Env *e;
Envval *ev;
@@ 456,19 456,19 @@ envread(Chan *c, void *va, long n)
lock(e);
ev = e->val;
vn = ev? e->val->len : 0;
- if(c->offset+n > vn)
- n = vn - c->offset;
+ if(offset+n > vn)
+ n = vn - offset;
if(n <= 0)
n = 0;
else
- memmove(a, ev->dat+c->offset, n);
+ memmove(a, ev->dat+offset, n);
unlock(e);
unlock(pg);
return n;
}
long
-envwrite(Chan *c, void *va, long n)
+envwrite(Chan *c, void *va, long n, ulong offset)
{
Env *e;
char *p;
@@ 496,13 496,13 @@ envwrite(Chan *c, void *va, long n)
}
if(e->pgref>1)
panic("envwrite to non-duped env");
- growenval(e, c->offset+n);
+ growenval(e, offset+n);
ev = e->val;
vn = ev? ev->len : 0;
- if(c->offset > vn)
+ if(offset > vn)
error(Egreg); /* perhaps should zero fill */
- memmove(ev->dat+c->offset, a, n);
- e->val->len = c->offset+n;
+ memmove(ev->dat+offset, a, n);
+ e->val->len = offset+n;
poperror();
unlock(e);
unlock(&envalloc);
M port/deviproute.c => port/deviproute.c +5 -5
@@ 268,7 268,7 @@ iprouteclose(Chan *c)
#define PAD " "
long
-iprouteread(Chan *c, void *a, long n)
+iprouteread(Chan *c, void *a, long n, ulong offset)
{
char buf[IPR_ENTRYLEN*3];
Iproute *r;
@@ 280,10 280,10 @@ iprouteread(Chan *c, void *a, long n)
return devdirread(c, a, n, iproutetab, Niproutetab, devgen);
case Qdata:
lock(&iprtab);
- part = c->offset/IPR_ENTRYLEN;
+ part = offset/IPR_ENTRYLEN;
for(r = iprtab.first; part && r; r = r->next)
part--;
- bytes = c->offset;
+ bytes = offset;
while(r && bytes < iprtab.n*IPR_ENTRYLEN && n){
part = bytes%IPR_ENTRYLEN;
@@ 309,7 309,7 @@ iprouteread(Chan *c, void *a, long n)
r = r->next;
}
unlock(&iprtab);
- return bytes - c->offset;
+ return bytes - offset;
break;
default:
n=0;
@@ 319,7 319,7 @@ iprouteread(Chan *c, void *a, long n)
}
long
-iproutewrite(Chan *c, char *a, long n)
+iproutewrite(Chan *c, char *a, long n, ulong offset)
{
char buf[IPR_ENTRYLEN];
char *field[4];
M port/devkprof.c => port/devkprof.c +6 -6
@@ 118,19 118,19 @@ kproferrstr(Error *e, char *buf)
}
long
-kprofread(Chan *c, void *a, long n)
+kprofread(Chan *c, void *a, long n, ulong offset)
{
switch((int)(c->qid&~CHDIR)){
case Kprofdirqid:
return devdirread(c, a, n, kproftab, Nkproftab, devgen);
case Kprofdataqid:
- if(c->offset >= NBUF*sizeof timerbuf[0]){
+ if(offset >= NBUF*sizeof timerbuf[0]){
n = 0;
break;
}
- if(c->offset+n > NBUF*sizeof timerbuf[0])
- n = NBUF*sizeof timerbuf[0]-c->offset;
- memmove(a, ((char *)timerbuf)+c->offset, n);
+ if(offset+n > NBUF*sizeof timerbuf[0])
+ n = NBUF*sizeof timerbuf[0]-offset;
+ memmove(a, ((char *)timerbuf)+offset, n);
break;
default:
n=0;
@@ 140,7 140,7 @@ kprofread(Chan *c, void *a, long n)
}
long
-kprofwrite(Chan *c, char *a, long n)
+kprofwrite(Chan *c, char *a, long n, ulong offset)
{
switch((int)(c->qid&~CHDIR)){
case Kprofstartclrqid:
M port/devlance.c => port/devlance.c +11 -11
@@ 623,40 623,40 @@ lanceclose(Chan *c)
}
static long
-lancetraceread(Chan *c, void *a, long n)
+lancetraceread(Chan *c, void *a, long n, ulong offset)
{
char buf[1024];
long rv;
int i;
char *ca = a;
- int offset;
+ int off;
Trace *t;
int plen;
rv = 0;
sprintpacket(buf, l.dq.t);
plen = strlen(buf);
- offset = c->offset % plen;
- for(t = &l.dq.t[c->offset/plen]; n && t < &l.dq.t[Ndpkt]; t++){
+ off = offset % plen;
+ for(t = &l.dq.t[offset/plen]; n && t < &l.dq.t[Ndpkt]; t++){
if(t->tag == 0)
break;
lock(&l.dq);
sprintpacket(buf, t);
unlock(&l.dq);
- i = plen - offset;
+ i = plen - off;
if(i > n)
i = n;
- memmove(ca, buf + offset, i);
+ memmove(ca, buf + off, i);
n -= i;
ca += i;
rv += i;
- offset = 0;
+ off = 0;
}
return rv;
}
long
-lanceread(Chan *c, void *a, long n)
+lanceread(Chan *c, void *a, long n, ulong offset)
{
char buf[256];
@@ 668,16 668,16 @@ lanceread(Chan *c, void *a, long n)
l.inpackets, l.outpackets, l.crcs,
l.overflows, l.frames, l.buffs, l.oerrs,
l.ea[0], l.ea[1], l.ea[2], l.ea[3], l.ea[4], l.ea[5]);
- return stringread(c, a, n, buf);
+ return stringread(c, a, n, buf, offset);
case Ltraceqid:
- return lancetraceread(c, a, n);
+ return lancetraceread(c, a, n, offset);
default:
return streamread(c, a, n);
}
}
long
-lancewrite(Chan *c, void *a, long n)
+lancewrite(Chan *c, void *a, long n, ulong offset)
{
return streamwrite(c, a, n, 0);
}
M port/devmnt.c => port/devmnt.c +10 -11
@@ 504,16 504,15 @@ mntclose(Chan *c)
}
long
-mntreadwrite(Chan *c, void *vbuf, long n, int type)
+mntreadwrite(Chan *c, void *vbuf, long n, int type, ulong offset)
{
Mnt *m;
Mnthdr *mh;
- long nt, nr, count, offset;
+ long nt, nr, count;
char *buf;
buf = vbuf;
count = 0;
- offset = c->offset;
m = mntdev(c->dev, 0);
mh = mhalloc();
if(waserror()){
@@ 543,12 542,12 @@ mntreadwrite(Chan *c, void *vbuf, long n, int type)
}
long
-mntread(Chan *c, void *buf, long n)
+mntread(Chan *c, void *buf, long n, ulong offset)
{
long i;
uchar *b;
- n = mntreadwrite(c, buf, n, Tread);
+ n = mntreadwrite(c, buf, n, Tread, offset);
if(c->qid.path & CHDIR){
b = (uchar*)buf;
for(i=n-DIRLEN; i>=0; i-=DIRLEN){
@@ 563,9 562,9 @@ mntread(Chan *c, void *buf, long n)
}
long
-mntwrite(Chan *c, void *buf, long n)
+mntwrite(Chan *c, void *buf, long n, ulong offset)
{
- return mntreadwrite(c, buf, n, Twrite);
+ return mntreadwrite(c, buf, n, Twrite, offset);
}
void
@@ 700,7 699,7 @@ mntxmit(Mnt *m, Mnthdr *mh)
mqfree(q);
nexterror();
}
- if((*devtab[q->msg->type].write)(q->msg, mbw->buf, n) != n){
+ if((*devtab[q->msg->type].write)(q->msg, mbw->buf, n, 0) != n){
print("short write in mntxmit\n");
error(Eshortmsg);
}
@@ 713,7 712,7 @@ mntxmit(Mnt *m, Mnthdr *mh)
nexterror();
}
mh->mbr = mballoc();
- n = (*devtab[q->msg->type].read)(q->msg, mh->mbr->buf, BUFSIZE);
+ n = (*devtab[q->msg->type].read)(q->msg, mh->mbr->buf, BUFSIZE, 0);
poperror(); /* 3 */
mqfree(q);
poperror(); /* 2 */
@@ 767,7 766,7 @@ mntxmit(Mnt *m, Mnthdr *mh)
}
mh->readreply = 0;
mh->active = 1;
- if((*devtab[q->msg->type].write)(q->msg, mbw->buf, n) != n){
+ if((*devtab[q->msg->type].write)(q->msg, mbw->buf, n, 0) != n){
print("short write in mntxmit\n");
error(Eshortmsg);
}
@@ 782,7 781,7 @@ mntxmit(Mnt *m, Mnthdr *mh)
nexterror();
}
mh->mbr = mballoc();
- n = (*devtab[q->msg->type].read)(q->msg, mh->mbr->buf, BUFSIZE);
+ n = (*devtab[q->msg->type].read)(q->msg, mh->mbr->buf, BUFSIZE, 0);
poperror(); /* 3 */
if(convM2S(mh->mbr->buf, &mh->rhdr, n) == 0){
mnterrdequeue(m, mh);
M port/devnonet.c => port/devnonet.c +6 -6
@@ 325,7 325,7 @@ nonetclose(Chan *c)
}
long
-nonetread(Chan *c, void *a, long n)
+nonetread(Chan *c, void *a, long n, ulong offset)
{
int t;
Noconv *cp;
@@ 346,21 346,21 @@ nonetread(Chan *c, void *a, long n)
cp = &noifc[c->dev].conv[STREAMID(c->qid.path)];
switch(t){
case Nraddrqid:
- return stringread(c, a, n, cp->raddr);
+ return stringread(c, a, n, cp->raddr, offset);
case Naddrqid:
- return stringread(c, a, n, cp->addr);
+ return stringread(c, a, n, cp->addr, offset);
case Nruserqid:
- return stringread(c, a, n, cp->ruser);
+ return stringread(c, a, n, cp->ruser, offset);
case Nstatsqid:
sprint(stats, "sent: %d\nrcved: %d\nrexmit: %d\nbad: %d\n",
cp->sent, cp->rcvd, cp->rexmit, cp->bad);
- return stringread(c, a, n, stats);
+ return stringread(c, a, n, stats, offset);
}
error(Eperm);
}
long
-nonetwrite(Chan *c, void *a, long n)
+nonetwrite(Chan *c, void *a, long n, ulong offset)
{
int t;
int m;
M port/devpipe.c => port/devpipe.c +2 -2
@@ 241,7 241,7 @@ pipeclose(Chan *c)
}
long
-piperead(Chan *c, void *va, long n)
+piperead(Chan *c, void *va, long n, ulong offset)
{
if(c->qid.path & CHDIR)
return devdirread(c, va, n, pipedir, NPIPEDIR, pipegen);
@@ 254,7 254,7 @@ piperead(Chan *c, void *va, long n)
* the process.
*/
long
-pipewrite(Chan *c, void *va, long n)
+pipewrite(Chan *c, void *va, long n, ulong offset)
{
if(waserror()){
postnote(u->p, 1, "sys: write on closed pipe", NExit);
M port/devproc.c => port/devproc.c +27 -27
@@ 144,9 144,9 @@ procopen(Chan *c, int omode)
goto Close;
if(p->pid != PID(c->qid))
goto Close;
- qlock(tc);
+ qlock(&tc->rdl);
tc->offset = 0;
- qunlock(tc);
+ qunlock(&tc->rdl);
return tc;
case Qctl:
case Qnote:
@@ 206,7 206,7 @@ procclose(Chan * c)
}
long
-procread(Chan *c, void *va, long n)
+procread(Chan *c, void *va, long n, ulong offset)
{
char *a = va, *b;
char statbuf[2*NAMELEN+12+6*12];
@@ 236,9 236,9 @@ procread(Chan *c, void *va, long n)
/*
* One page at a time
*/
- if(((c->offset+n)&~(BY2PG-1)) != (c->offset&~(BY2PG-1)))
- n = BY2PG - (c->offset&(BY2PG-1));
- s = seg(p, c->offset);
+ if(((offset+n)&~(BY2PG-1)) != (offset&~(BY2PG-1)))
+ n = BY2PG - (offset&(BY2PG-1));
+ s = seg(p, offset);
if(s){
o = s->o;
if(o == 0)
@@ 248,11 248,11 @@ procread(Chan *c, void *va, long n)
unlock(o);
error(Eprocdied);
}
- if(seg(p, c->offset) != s){
+ if(seg(p, offset) != s){
unlock(o);
error(Egreg);
}
- pte = &o->pte[(c->offset-o->va)>>PGSHIFT];
+ pte = &o->pte[(offset-o->va)>>PGSHIFT];
if(s->mod){
opte = pte;
while(pte = pte->nextmod) /* assign = */
@@ 264,35 264,35 @@ procread(Chan *c, void *va, long n)
pg = pte->page;
unlock(o);
if(pg == 0){
- pprint("nonresident page addr %lux (complain to rob)\n", c->offset);
+ pprint("nonresident page addr %lux (complain to rob)\n", offset);
memset(a, 0, n);
}else{
k = kmap(pg);
b = (char*)VA(k);
- memmove(a, b+(c->offset&(BY2PG-1)), n);
+ memmove(a, b+(offset&(BY2PG-1)), n);
kunmap(k);
}
return n;
}
/* u area */
- if(c->offset>=USERADDR && c->offset<USERADDR+BY2PG){
- if(c->offset+n > USERADDR+BY2PG)
- n = USERADDR+BY2PG - c->offset;
+ if(offset>=USERADDR && offset<USERADDR+BY2PG){
+ if(offset+n > USERADDR+BY2PG)
+ n = USERADDR+BY2PG - offset;
pg = p->upage;
if(pg==0 || p->pid!=PID(c->qid))
error(Eprocdied);
k = kmap(pg);
b = (char*)VA(k);
- memmove(a, b+(c->offset-USERADDR), n);
+ memmove(a, b+(offset-USERADDR), n);
kunmap(k);
return n;
}
/* kernel memory. BUG: shouldn't be so easygoing. BUG: mem mapping? */
- if(c->offset>=KZERO && c->offset<KZERO+conf.npage0*BY2PG){
- if(c->offset+n > KZERO+conf.npage0*BY2PG)
- n = KZERO+conf.npage0*BY2PG - c->offset;
- memmove(a, (char*)c->offset, n);
+ if(offset>=KZERO && offset<KZERO+conf.npage0*BY2PG){
+ if(offset+n > KZERO+conf.npage0*BY2PG)
+ n = KZERO+conf.npage0*BY2PG - offset;
+ memmove(a, (char*)offset, n);
return n;
}
return 0;
@@ 328,18 328,18 @@ procread(Chan *c, void *va, long n)
return n;
case Qproc:
- if(c->offset >= sizeof(Proc))
+ if(offset >= sizeof(Proc))
return 0;
- if(c->offset+n > sizeof(Proc))
- n = sizeof(Proc) - c->offset;
- memmove(a, ((char*)p)+c->offset, n);
+ if(offset+n > sizeof(Proc))
+ n = sizeof(Proc) - offset;
+ memmove(a, ((char*)p)+offset, n);
return n;
case Qstatus:
- if(c->offset >= sizeof statbuf)
+ if(offset >= sizeof statbuf)
return 0;
- if(c->offset+n > sizeof statbuf)
- n = sizeof statbuf - c->offset;
+ if(offset+n > sizeof statbuf)
+ n = sizeof statbuf - offset;
sprint(statbuf, "%-27s %-27s %-11s ", p->text, p->pgrp->user, statename[p->state]);
for(i=0; i<6; i++){
l = p->time[i];
@@ 348,7 348,7 @@ procread(Chan *c, void *va, long n)
l = TK2MS(l);
readnum(0, statbuf+2*NAMELEN+12+NUMSIZE*i, NUMSIZE, l, NUMSIZE);
}
- memmove(a, statbuf+c->offset, n);
+ memmove(a, statbuf+offset, n);
return n;
}
error(Egreg);
@@ 356,7 356,7 @@ procread(Chan *c, void *va, long n)
long
-procwrite(Chan *c, void *va, long n)
+procwrite(Chan *c, void *va, long n, ulong offset)
{
Proc *p;
Pgrp *pg;
M port/devroot.c => port/devroot.c +10 -10
@@ 90,7 90,7 @@ rootclose(Chan *c)
#include "boot.h"
long
-rootread(Chan *c, void *buf, long n)
+rootread(Chan *c, void *buf, long n, ulong offset)
{
switch(c->qid.path & ~CHDIR){
@@ 98,19 98,19 @@ rootread(Chan *c, void *buf, long n)
return devdirread(c, buf, n, rootdir, nroot, devgen);
case Qboot: /* boot */
- if(c->offset >= sizeof bootcode)
+ if(offset >= sizeof bootcode)
return 0;
- if(c->offset+n > sizeof bootcode)
- n = sizeof bootcode - c->offset;
- memmove(buf, ((char*)bootcode)+c->offset, n);
+ if(offset+n > sizeof bootcode)
+ n = sizeof bootcode - offset;
+ memmove(buf, ((char*)bootcode)+offset, n);
return n;
case Qcfs: /* cfs */
- if(c->offset >= cfslen)
+ if(offset >= cfslen)
return 0;
- if(c->offset+n > cfslen)
- n = cfslen - c->offset;
- memmove(buf, ((char*)cfscode)+c->offset, n);
+ if(offset+n > cfslen)
+ n = cfslen - offset;
+ memmove(buf, ((char*)cfscode)+offset, n);
return n;
case Qdev:
@@ 121,7 121,7 @@ rootread(Chan *c, void *buf, long n)
}
long
-rootwrite(Chan *c, void *buf, long n)
+rootwrite(Chan *c, void *buf, long n, ulong offset)
{
error(Egreg);
}
M port/devscsi.c => port/devscsi.c +6 -6
@@ 117,7 117,7 @@ scsiclose(Chan *c)
{}
long
-scsiread(Chan *c, char *a, long n)
+scsiread(Chan *c, char *a, long n, ulong offset)
{
Scsi *cmd = &staticcmd;
if (n == 0)
@@ 125,7 125,7 @@ scsiread(Chan *c, char *a, long n)
if(c->qid.path & CHDIR)
return devdirread(c, a, n, 0, 0, scsigen);
if(c->qid.path==1){
- if(c->offset == 0){
+ if(offset == 0){
*a = ownid;
n = 1;
}else
@@ 155,7 155,7 @@ scsiread(Chan *c, char *a, long n)
memmove(a, cmd->data.base, n);
break;
case Qdebug:
- if (c->offset == 0) {
+ if (offset == 0) {
n=1;
*a="01"[debugs[(c->qid.path>>4)&7]!=0];
} else
@@ 168,11 168,11 @@ scsiread(Chan *c, char *a, long n)
}
long
-scsiwrite(Chan *c, char *a, long n)
+scsiwrite(Chan *c, char *a, long n, ulong offset)
{
Scsi *cmd = &staticcmd;
if(c->qid.path==1 && n>0){
- if(c->offset == 0){
+ if(offset == 0){
n = 1;
ownid=*a;
scsiinit();
@@ 204,7 204,7 @@ scsiwrite(Chan *c, char *a, long n)
n = cmd->data.ptr - cmd->data.base;
break;
case Qdebug:
- if (c->offset == 0) {
+ if (offset == 0) {
debugs[(c->qid.path>>4)&7] = (*a=='1');
n = 1;
} else
M port/devsrv.c => port/devsrv.c +2 -4
@@ 231,13 231,11 @@ srvdirentry(Entry *e, char *a, long count){
}
long
-srvread(Chan *c, void *va, long n)
+srvread(Chan *c, void *va, long n, ulong offset)
{
Entry *dir, *e;
- int offset;
dir = c->aux;
- offset = c->offset;
isdir(c);
if(n <= 0)
return 0;
@@ 257,7 255,7 @@ srvread(Chan *c, void *va, long n)
}
long
-srvwrite(Chan *c, void *va, long n)
+srvwrite(Chan *c, void *va, long n, ulong offset)
{
Entry *e;
int i, fd;
M port/devwren.c => port/devwren.c +7 -7
@@ 202,7 202,7 @@ wrenclose(Chan *c)
#define PSHORT(p, v) ((p)[0]=(v), (p)[1]=((v)>>8))
#define PLONG(p, v) (PSHORT(p, (v)), PSHORT(p+2, (v)>>16))
long
-wrenread(Chan *c, char *a, long n)
+wrenread(Chan *c, char *a, long n, ulong offset)
{
Scsi *cmd = &staticcmd;
unsigned long lbn;
@@ 219,9 219,9 @@ wrenread(Chan *c, char *a, long n)
p = &(d->p[Mask&c->qid.path]);
switch ((int)(c->qid.path & ~Mask)) {
case Qdata:
- if (n % d->blocksize || c->offset % d->blocksize)
+ if (n % d->blocksize || offset % d->blocksize)
error(Ebadarg);
- lbn = (c->offset/d->blocksize) + p->firstblock;
+ lbn = (offset/d->blocksize) + p->firstblock;
if (lbn >= p->maxblock)
error(Ebadarg);
if (n > sizeof datablk)
@@ 252,7 252,7 @@ wrenread(Chan *c, char *a, long n)
case Qstruct:
if (n < 8)
error(Ebadarg);
- if (c->offset >= 8)
+ if (offset >= 8)
return 0;
n = 8;
PLONG((uchar *)&a[0], p->maxblock - p->firstblock);
@@ 265,7 265,7 @@ wrenread(Chan *c, char *a, long n)
}
long
-wrenwrite(Chan *c, char *a, long n)
+wrenwrite(Chan *c, char *a, long n, ulong offset)
{
Scsi *cmd = &staticcmd;
unsigned long lbn;
@@ 279,9 279,9 @@ wrenwrite(Chan *c, char *a, long n)
p = &(d->p[Mask&c->qid.path]);
switch ((int)(c->qid.path & ~Mask)) {
case Qdata:
- if (n % d->blocksize || c->offset % d->blocksize)
+ if (n % d->blocksize || offset % d->blocksize)
error(Ebadarg);
- lbn = c->offset/d->blocksize + p->firstblock;
+ lbn = offset/d->blocksize + p->firstblock;
if (lbn >= p->maxblock)
error(Ebadarg);
if (n > sizeof datablk)
M port/fault.c => port/fault.c +4 -5
@@ 79,20 79,19 @@ fault(ulong addr, int read)
n = BY2PG;
pg = newpage(1, o, addr);
k = kmap(pg);
- qlock(o->chan);
+ qlock(&o->chan->rdl);
if(waserror()){
kunmap(k);
- qunlock(o->chan);
+ qunlock(&o->chan->rdl);
pg->o = 0;
pg->ref--;
pexit("load i/o error", 0);
}
- o->chan->offset = (addr-o->va) + o->minca;
l = (char*)VA(k);
- if((*devtab[o->chan->type].read)(o->chan, l, n) != n)
+ if((*devtab[o->chan->type].read)(o->chan, l, n, (addr-o->va) + o->minca) != n)
error(Eioload);
flushpage(pg->pa);
- qunlock(o->chan);
+ qunlock(&o->chan->rdl);
if(n<BY2PG)
memset(l+n, 0, BY2PG-n);
lock(o);
M port/stream.c => port/stream.c +24 -8
@@ 790,6 790,7 @@ streamnew(ushort type, ushort dev, ushort id, Qinfo *qi, int noopen)
s->type = type;
s->dev = dev;
s->id = id;
+ s->err = 0;
/*
* hang a device and process q off the stream
@@ 801,6 802,8 @@ streamnew(ushort type, ushort dev, ushort id, Qinfo *qi, int noopen)
s->opens = 1;
s->hread = 0;
q = allocq(&procinfo);
+ WR(q)->ptr = s;
+ RD(q)->ptr = s;
s->procq = WR(q);
q = allocq(qi);
s->devq = RD(q);
@@ 895,6 898,8 @@ streamexit(Stream *s, int locked)
freeq(q);
}
s->id = s->dev = s->type = 0;
+ if(s->err)
+ freeb(s->err);
}
s->inuse--;
rv = s->inuse;
@@ 972,9 977,14 @@ void
stputq(Queue *q, Block *bp)
{
int delim;
+ Stream *s;
if(bp->type == M_HANGUP){
- freeb(bp);
+ s = q->ptr;
+ if(bp->rptr<bp->wptr && s->err==0)
+ s->err = bp;
+ else
+ freeb(bp);
q->flag |= QHUNGUP;
q->other->flag |= QHUNGUP;
wakeup(q->other->rp);
@@ 1009,17 1019,17 @@ stputq(Queue *q, Block *bp)
* read a string. update the offset accordingly.
*/
long
-stringread(Chan *c, uchar *buf, long n, char *str)
+stringread(Chan *c, uchar *buf, long n, char *str, ulong offset)
{
long i;
i = strlen(str);
- i -= c->offset;
+ i -= offset;
if(i<n)
n = i;
if(n<0)
return 0;
- memmove(buf, str + c->offset, n);
+ memmove(buf, str + offset, n);
return n;
}
@@ 1036,7 1046,7 @@ streamctlread(Chan *c, void *vbuf, long n)
s = c->stream;
if(STREAMTYPE(c->qid.path) == Sctlqid){
sprint(num, "%d", s->id);
- return stringread(c, buf, n, num);
+ return stringread(c, buf, n, num, c->offset);
} else {
if(CHDIR & c->qid.path)
return devdirread(c, vbuf, n, 0, 0, streamgen);
@@ 1091,7 1101,9 @@ streamread(Chan *c, void *vbuf, long n)
bp = getq(q);
if(bp == 0){
if(q->flag & QHUNGUP){
- if(s->hread++ < 3)
+ if(s->err)
+ errors((char*)s->err->rptr);
+ else if(s->hread++<3)
break;
else
error(Ehungup);
@@ 1246,8 1258,12 @@ streamwrite(Chan *c, void *a, long n, int docopy)
* No writes allowed on hungup channels
*/
q = s->procq;
- if(q->other->flag & QHUNGUP)
- error(Ehungup);
+ if(q->other->flag & QHUNGUP){
+ if(s->err)
+ errors((char*)(s->err->rptr));
+ else
+ error(Ehungup);
+ }
if(!docopy && isphys(a)){
/*
M port/sysfile.c => port/sysfile.c +15 -12
@@ 191,7 191,7 @@ unionread(Chan *c, void *va, long n)
}
nc = (*devtab[nc->type].open)(nc, OREAD);
nc->offset = c->offset;
- nr = (*devtab[nc->type].read)(nc, va, n);
+ nr = (*devtab[nc->type].read)(nc, va, n, nc->offset);
c->offset = nc->offset; /* devdirread e.g. changes it */
close(nc);
poperror();
@@ 226,9 226,9 @@ sysread(ulong *arg)
c = fdtochan(arg[0], OREAD);
validaddr(arg[1], arg[2], 1);
- qlock(c);
+ qlock(&c->rdl);
if(waserror()){
- qunlock(c);
+ qunlock(&c->rdl);
nexterror();
}
n = arg[2];
@@ 240,9 240,9 @@ sysread(ulong *arg)
if((c->qid.path&CHDIR) && (c->flag&CMOUNT))
n = unionread(c, (void*)arg[1], n);
else
- n = (*devtab[c->type].read)(c, (void*)arg[1], n);
+ n = (*devtab[c->type].read)(c, (void*)arg[1], n, c->offset);
c->offset += n;
- qunlock(c);
+ qunlock(&c->rdl);
return n;
}
@@ 254,16 254,16 @@ syswrite(ulong *arg)
c = fdtochan(arg[0], OWRITE);
validaddr(arg[1], arg[2], 0);
- qlock(c);
+ qlock(&c->wrl);
if(waserror()){
- qunlock(c);
+ qunlock(&c->wrl);
nexterror();
}
if(c->qid.path & CHDIR)
error(Eisdir);
- n = (*devtab[c->type].write)(c, (void*)arg[1], arg[2]);
+ n = (*devtab[c->type].write)(c, (void*)arg[1], arg[2], c->offset);
c->offset += n;
- qunlock(c);
+ qunlock(&c->wrl);
return n;
}
@@ 280,9 280,11 @@ sysseek(ulong *arg)
error(Eisdir);
if(devchar[c->type] == '|')
error(Eisstream);
- qlock(c);
+ qlock(&c->rdl);
+ qlock(&c->wrl);
if(waserror()){
- qunlock(c);
+ qunlock(&c->rdl);
+ qunlock(&c->wrl);
nexterror();
}
switch(arg[2]){
@@ 301,7 303,8 @@ sysseek(ulong *arg)
break;
}
off = c->offset;
- qunlock(c);
+ qunlock(&c->rdl);
+ qunlock(&c->wrl);
poperror();
return off;
}
M port/sysproc.c => port/sysproc.c +1 -1
@@ 170,7 170,7 @@ sysexec(ulong *arg)
}
if(!indir)
strcpy(elem, u->elem);
- n = (*devtab[tc->type].read)(tc, &exec, sizeof(Exec));
+ n = (*devtab[tc->type].read)(tc, &exec, sizeof(Exec), 0);
if(n < 2)
Err:
error(Ebadexec);
M power/dat.h => power/dat.h +5 -3
@@ 106,7 106,8 @@ struct Hotmsg
#define CHDIR 0x80000000L
struct Chan
{
- QLock; /* general access */
+ QLock rdl; /* read access */
+ QLock wrl; /* write access */
Ref;
union{
Chan *next; /* allocation */
@@ 181,8 182,8 @@ struct Dev
Chan *(*open)(Chan*, int);
void (*create)(Chan*, char*, int, ulong);
void (*close)(Chan*);
- long (*read)(Chan*, void*, long);
- long (*write)(Chan*, void*, long);
+ long (*read)(Chan*, void*, long, ulong);
+ long (*write)(Chan*, void*, long, ulong);
void (*remove)(Chan*);
void (*wstat)(Chan*, char*);
};
@@ 481,6 482,7 @@ struct Stream {
QLock rdlock; /* read lock */
Queue *procq; /* write queue at process end */
Queue *devq; /* read queue at device end */
+ Block *err; /* error message from down stream */
};
#define RD(q) ((q)->other < (q) ? (q->other) : q)
#define WR(q) ((q)->other > (q) ? (q->other) : q)
M power/devbit3.c => power/devbit3.c +2 -2
@@ 130,7 130,7 @@ bit3close(Chan *c)
*/
long
-bit3read(Chan *c, void *buf, long n)
+bit3read(Chan *c, void *buf, long n, ulong offset)
{
Bit3msg *bp;
int docpy;
@@ 174,7 174,7 @@ bit3read(Chan *c, void *buf, long n)
}
long
-bit3write(Chan *c, void *buf, long n)
+bit3write(Chan *c, void *buf, long n, ulong offset)
{
Bit3msg *bp;
M power/devhotrod.c => power/devhotrod.c +2 -2
@@ 272,7 272,7 @@ hotmsgintr(Hotmsg *hm)
*/
long
-hotrodread(Chan *c, void *buf, long n)
+hotrodread(Chan *c, void *buf, long n, ulong offset)
{
Hotrod *hp;
Hotmsg *mp, **hmp;
@@ 389,7 389,7 @@ hotrodread(Chan *c, void *buf, long n)
}
long
-hotrodwrite(Chan *c, void *buf, long n)
+hotrodwrite(Chan *c, void *buf, long n, ulong offset)
{
Hotrod *hp;
Hotmsg *mp, **hmp;
M power/devhs.c => power/devhs.c +2 -2
@@ 218,13 218,13 @@ hsvmeclose(Chan *c)
}
long
-hsvmeread(Chan *c, void *buf, long n)
+hsvmeread(Chan *c, void *buf, long n, ulong offset)
{
return streamread(c, buf, n);
}
long
-hsvmewrite(Chan *c, void *buf, long n)
+hsvmewrite(Chan *c, void *buf, long n, ulong offset)
{
return streamwrite(c, buf, n, 0);
}
M power/devrtc.c => power/devrtc.c +4 -4
@@ 137,7 137,7 @@ rtcclose(Chan *c)
#define GETBCD(o) ((bcdclock[o]&0xf) + 10*(bcdclock[o]>>4))
long
-rtcread(Chan *c, void *buf, long n)
+rtcread(Chan *c, void *buf, long n, ulong offset)
{
int i,j;
uchar ch;
@@ 192,13 192,13 @@ rtcread(Chan *c, void *buf, long n)
else
rtc.year += 1900;
- return readnum(c->offset, buf, n, rtc2sec(&rtc), 12);
+ return readnum(offset, buf, n, rtc2sec(&rtc), 12);
}
#define PUTBCD(n,o) bcdclock[o] = (n % 10) | (((n / 10) % 10)<<4)
long
-rtcwrite(Chan *c, void *buf, long n)
+rtcwrite(Chan *c, void *buf, long n, ulong offset)
{
Rtc rtc;
ulong secs;
@@ 208,7 208,7 @@ rtcwrite(Chan *c, void *buf, long n)
uchar *nv;
char *cp, *ep;
- if(c->offset!=0)
+ if(offset!=0)
error(Ebadarg);
/*
M power/fns.h => power/fns.h +1 -1
@@ 186,7 186,7 @@ Stream *streamnew(ushort, ushort, ushort, Qinfo*, int);
void streamopen(Chan*, Qinfo*);
int streamparse(char*, Block*);
void streamstat(Chan*, char*, char*);
-long stringread(Chan*, void*, long, char*);
+long stringread(Chan*, void*, long, char*, ulong);
long syscall(Ureg*);
void sysloginit(void);
void syslog(char*, int);
M ss/dat.h => ss/dat.h +3 -2
@@ 173,8 173,8 @@ struct Dev
Chan *(*open)(Chan*, int);
void (*create)(Chan*, char*, int, ulong);
void (*close)(Chan*);
- long (*read)(Chan*, void*, long);
- long (*write)(Chan*, void*, long);
+ long (*read)(Chan*, void*, long, ulong);
+ long (*write)(Chan*, void*, long, ulong );
void (*remove)(Chan*);
void (*wstat)(Chan*, char*);
};
@@ 478,6 478,7 @@ struct Stream {
QLock rdlock; /* read lock */
Queue *procq; /* write queue at process end */
Queue *devq; /* read queue at device end */
+ Block *err; /* error message from down stream */
};
#define RD(q) ((q)->other < (q) ? (q->other) : q)
#define WR(q) ((q)->other > (q) ? (q->other) : q)
M ss/mem.h => ss/mem.h +1 -1
@@ 132,4 132,4 @@
#define NSEG 5
#define MACHSIZE 4096
-#define isphys(x) ((((ulong)(x)&0xF0000000) == KZERO)
+#define isphys(x) (((ulong)(x)&0xF0000000) == KZERO)