M alphapc/trap.c => alphapc/trap.c +2 -0
@@ 703,6 703,8 @@ print("bad sys call %d pc %lux\n", up->scallnr, (ulong)ur->pc);
poperror();
error:
+ /* failure: save the error buffer for errstr */
+ kstrcpy(up->syserror, up->error, sizeof up->syserror);
up->nerrlab = 0;
up->psstate = 0;
up->insyscall = 0;
M bitsy/devpenmouse.c => bitsy/devpenmouse.c +4 -1
@@ 92,7 92,10 @@ extern Memimage* gscreen;
void
penbutton(int up, int b) {
- if (b & 0x20) {
+ // button 5 (side button) immediately causes an event
+ // when the pen is down (button 1), other buttons also
+ // cause events, allowing chording with button 1
+ if ((b & 0x20) || (mouse.buttons & 0x1)) {
if (up)
mouse.buttons &= ~b;
else
M bitsy/l.s => bitsy/l.s +2 -1
@@ 688,7 688,8 @@ TEXT power_down(SB), $-4
MOVW R2,0x10(R3)
MOVW $0,R2
MOVW R2,0x18(R3)
- MOVW $power_resume+0(SB),R2
+/* MOVW $power_resume+0(SB),R2 */
+ MOVW $0,R2
MOVW R2,0x8(R3)
MOVW $0,R2
MOVW R2,0x4(R6)
M bitsy/power.c => bitsy/power.c +0 -2
@@ 275,7 275,6 @@ powerinit(void)
void
idlehands(void)
{
-#ifdef notdef
char *msgb = "idlehands called with splhi\n";
char *msga = "doze returns with splhi\n";
@@ 288,6 287,5 @@ idlehands(void)
serialputs(msgb, strlen(msgb));
spllo();
}
-#endif
}
M bitsy/trap.c => bitsy/trap.c +3 -0
@@ 462,6 462,9 @@ syscall(Ureg* ureg)
ret = systab[scallnr](up->s.args);
poperror();
+ }else{
+ /* failure: save the error buffer for errstr */
+ kstrcpy(up->syserror, up->error, sizeof up->syserror);
}
if(up->nerrlab){
print("bad errstack [%d]: %d extra\n", scallnr, up->nerrlab);
M mtx/trap.c => mtx/trap.c +3 -0
@@ 653,6 653,9 @@ syscall(Ureg* ureg)
ret = systab[scallnr](up->s.args);
poperror();
+ }else{
+ /* failure: save the error buffer for errstr */
+ kstrcpy(up->syserror, up->error, sizeof up->syserror);
}
if(up->nerrlab){
print("bad errstack [%d]: %d extra\n", scallnr, up->nerrlab);
M pc/devvga.c => pc/devvga.c +1 -0
@@ 276,6 276,7 @@ vgactl(char* a)
return;
}
else if(strcmp(field[0], "drawinit") == 0){
+ memimagedraw(scr->gscreen, scr->gscreen->r, memblack, ZP, nil, ZP);
if(scr && scr->dev && scr->dev->drawinit)
scr->dev->drawinit(scr);
return;
M pc/ether79c970.c => pc/ether79c970.c +112 -63
@@ 1,5 1,5 @@
/*
- * AM79C970
+ * AMD79C970
* PCnet-PCI Single-Chip Ethernet Controller for PCI Local Bus
* To do:
* finish this rewrite
@@ 108,7 108,7 @@ enum { /* md2 */
};
typedef struct Ctlr Ctlr;
-typedef struct Ctlr {
+struct Ctlr {
Lock;
int port;
Pcidev* pcidev;
@@ 140,28 140,49 @@ typedef struct Ctlr {
ulong merr; /* bobf is such a whiner */
ulong miss;
ulong babl;
-} Ctlr;
+
+ int (*ior)(Ctlr*, int);
+ void (*iow)(Ctlr*, int, int);
+};
static Ctlr* ctlrhead;
static Ctlr* ctlrtail;
-#define csr32r(c, r) (inl((c)->port+(r)))
-#define csr32w(c, r, l) (outl((c)->port+(r), (ulong)(l)))
+/*
+ * The Rdp, Rap, Sreset, Bdp ports are 32-bit port offset in the enumeration above.
+ * To get to 16-bit offsets, scale down with 0x10 staying the same.
+ */
+static int
+io16r(Ctlr *c, int r)
+{
+ if(r >= Rdp)
+ r = (r-Rdp)/2+Rdp;
+ return ins(c->port+r);
+}
static void
-attach(Ether* ether)
+io16w(Ctlr *c, int r, int v)
{
- Ctlr *ctlr;
+ if(r >= Rdp)
+ r = (r-Rdp)/2+Rdp;
+ outs(c->port+r, v);
+}
- ctlr = ether->ctlr;
+static int
+io32r(Ctlr *c, int r)
+{
+ return inl(c->port+r);
+}
- ilock(ctlr);
- if(ctlr->init){
- iunlock(ctlr);
- return;
- }
- csr32w(ctlr, Rdp, Iena|Strt);
- iunlock(ctlr);
+static void
+io32w(Ctlr *c, int r, int v)
+{
+ outl(c->port+r, v);
+}
+
+static void
+attach(Ether*)
+{
}
static long
@@ 260,20 281,20 @@ promiscuous(void* arg, int on)
while(ctlr->ntq)
;
- csr32w(ctlr, Rdp, Stop);
+ ctlr->iow(ctlr, Rdp, Stop);
- csr32w(ctlr, Rap, 15);
- x = csr32r(ctlr, Rdp) & ~Prom;
+ ctlr->iow(ctlr, Rap, 15);
+ x = ctlr->ior(ctlr, Rdp) & ~Prom;
if(on)
x |= Prom;
- csr32w(ctlr, Rdp, x);
- csr32w(ctlr, Rap, 0);
+ ctlr->iow(ctlr, Rdp, x);
+ ctlr->iow(ctlr, Rap, 0);
ringinit(ctlr);
ilock(ctlr);
ctlr->init = 0;
- csr32w(ctlr, Rdp, Iena|Strt);
+ ctlr->iow(ctlr, Rdp, Iena|Strt);
iunlock(ctlr);
}
@@ 299,7 320,7 @@ txstart(Ether* ether)
* increment the software ring descriptor pointer
* and tell the chip to poll.
* There's no need to pad to ETHERMINTU
- * here as ApadXmit is set in CSR4.
+ * here as ApadXmt is set in CSR4.
*/
dre = &ctlr->tdr[ctlr->tdrh];
dre->bp = bp;
@@ 307,7 328,7 @@ txstart(Ether* ether)
dre->md2 = 0;
dre->md1 = Own|Stp|Enp|(-BLEN(bp) & 0xFFFF);
ctlr->ntq++;
- csr32w(ctlr, Rdp, Iena|Tdmd);
+ ctlr->iow(ctlr, Rdp, Iena|Tdmd);
ctlr->tdrh = NEXT(ctlr->tdrh, Ntdre);
}
}
@@ 340,8 361,8 @@ interrupt(Ureg*, void* arg)
* happen.
*/
intrloop:
- csr0 = csr32r(ctlr, Rdp) & 0xFFFF;
- csr32w(ctlr, Rdp, Babl|Cerr|Miss|Merr|Rint|Tint|Iena);
+ csr0 = ctlr->ior(ctlr, Rdp) & 0xFFFF;
+ ctlr->iow(ctlr, Rdp, Babl|Cerr|Miss|Merr|Rint|Tint|Iena);
if(csr0 & Merr)
ctlr->merr++;
if(csr0 & Miss)
@@ 488,46 509,67 @@ reset(Ether* ether)
ilock(ctlr);
ctlr->init = 1;
+ io32r(ctlr, Sreset);
+ io16r(ctlr, Sreset);
+
+ if(io16w(ctlr, Rap, 0), io16r(ctlr, Rdp) == 4){
+ ctlr->ior = io16r;
+ ctlr->iow = io16w;
+ }else if(io32w(ctlr, Rap, 0), io32r(ctlr, Rdp) == 4){
+ ctlr->ior = io32r;
+ ctlr->iow = io32w;
+ }else{
+ print("#l%d: card doesn't talk right\n", ether->ctlrno);
+ iunlock(ctlr);
+ return -1;
+ }
+
+ ctlr->iow(ctlr, Rap, 88);
+ x = ctlr->ior(ctlr, Rdp);
+ ctlr->iow(ctlr, Rap, 89);
+ x |= ctlr->ior(ctlr, Rdp)<<16;
+
+ switch(x&0xFFFFFFF){
+ case 0x2420003: /* PCnet/PCI 79C970 */
+ case 0x2621003: /* PCnet/PCI II 79C970A */
+ break;
+ default:
+ print("#l%d: unknown PCnet card version %.7ux\n",
+ ether->ctlrno, x&0xFFFFFFF);
+ iunlock(ctlr);
+ return -1;
+ }
+
/*
- * How to tell what mode the chip is in at this point - if it's in WORD
- * mode then the only 32-bit access allowed is a write to the RDP, which
- * forces the chip to DWORD mode; if it's in DWORD mode then only DWORD
- * accesses are allowed?
- * Assuming a DWORD write is done to the RDP, what will be overwritten as
- * the RAP can't reliably be accessed?
- *
- * Force DWORD mode by writing to RDP, doing a reset then writing to RDP
- * again. The value of RAP after a reset is 0, so the second DWORD write
- * will be to CSR0.
* Set the software style in BCR20 to be PCnet-PCI to ensure 32-bit access.
* Set the auto pad transmit in CSR4.
*/
- csr32w(ctlr, Rdp, 0x00);
- csr32r(ctlr, Sreset);
- csr32w(ctlr, Rdp, Stop);
-
- csr32w(ctlr, Rap, 20);
- csr32w(ctlr, Bdp, 0x0002);
+ ctlr->iow(ctlr, Rap, 20);
+ ctlr->iow(ctlr, Bdp, 0x0002);
- csr32w(ctlr, Rap, 4);
- x = csr32r(ctlr, Rdp) & 0xFFFF;
- csr32w(ctlr, Rdp, ApadXmt|x);
+ ctlr->iow(ctlr, Rap, 4);
+ x = ctlr->ior(ctlr, Rdp) & 0xFFFF;
+ ctlr->iow(ctlr, Rdp, ApadXmt|x);
- csr32w(ctlr, Rap, 0);
+ ctlr->iow(ctlr, Rap, 0);
/*
- * Check if the adapter's station address is to be over-ridden.
- * If not, read it from the I/O-space and set in ether->ea prior to loading the
- * station address in the initialisation block.
+ * Check if the adapter's station address is to be overridden.
+ * If not, read it from the I/O-space and set in ether->ea prior to
+ * loading the station address in the initialisation block.
*/
memset(ea, 0, Eaddrlen);
if(!memcmp(ea, ether->ea, Eaddrlen)){
- x = csr32r(ctlr, Aprom);
+ x = ctlr->ior(ctlr, Aprom);
ether->ea[0] = x;
ether->ea[1] = x>>8;
- ether->ea[2] = x>>16;
- ether->ea[3] = x>>24;
- x = csr32r(ctlr, Aprom+4);
+ if(ctlr->ior == io16r)
+ x = ctlr->ior(ctlr, Aprom+2);
+ else
+ x >>= 16;
+ ether->ea[2] = x;
+ ether->ea[3] = x>>8;
+ x = ctlr->ior(ctlr, Aprom+4);
ether->ea[4] = x;
ether->ea[5] = x>>8;
}
@@ 550,18 592,25 @@ reset(Ether* ether)
* enables will be set later when attaching to the network.
*/
x = PADDR(&ctlr->iblock);
- csr32w(ctlr, Rap, 1);
- csr32w(ctlr, Rdp, x & 0xFFFF);
- csr32w(ctlr, Rap, 2);
- csr32w(ctlr, Rdp, (x>>16) & 0xFFFF);
- csr32w(ctlr, Rap, 3);
- csr32w(ctlr, Rdp, Idon);
- csr32w(ctlr, Rap, 0);
- csr32w(ctlr, Rdp, Init);
-
- while(!(csr32r(ctlr, Rdp) & Idon))
+ ctlr->iow(ctlr, Rap, 1);
+ ctlr->iow(ctlr, Rdp, x & 0xFFFF);
+ ctlr->iow(ctlr, Rap, 2);
+ ctlr->iow(ctlr, Rdp, (x>>16) & 0xFFFF);
+ ctlr->iow(ctlr, Rap, 3);
+ ctlr->iow(ctlr, Rdp, Idon);
+ ctlr->iow(ctlr, Rap, 0);
+ ctlr->iow(ctlr, Rdp, Init);
+
+ while(!(ctlr->ior(ctlr, Rdp) & Idon))
;
- csr32w(ctlr, Rdp, Idon|Stop);
+
+ /*
+ * We used to set CSR0 to Idon|Stop here, and then
+ * in attach change it to Iena|Strt. Apparently the simulated
+ * 79C970 in VMware never enables after a write of Idon|Stop,
+ * so we enable the device here now.
+ */
+ ctlr->iow(ctlr, Rdp, Iena|Strt);
ctlr->init = 0;
iunlock(ctlr);
M pc/screen.c => pc/screen.c +0 -3
@@ 72,9 72,6 @@ screensize(int x, int y, int z, ulong chan)
if(gscreen == nil)
return -1;
-/* memset(gscreen->data->bdata, 0x15, (x*y*z+7)/8); /* RSC BUG */
- memfillcolor(gscreen, DRed);
-
scr->palettedepth = 6; /* default */
scr->gscreendata = &gscreendata;
scr->memdefont = getmemdefont();
M pc/sdata.c => pc/sdata.c +0 -5
@@ 1590,14 1590,12 @@ atapnp(void)
Pcidev *p;
int channel, ispc87415, pi, r;
SDev *legacy[2], *sdev, *head, *tail;
-//int i;
legacy[0] = legacy[1] = head = tail = nil;
if(sdev = ataprobe(0x1F0, 0x3F4, IrqATA0)){
head = tail = sdev;
legacy[0] = sdev;
}
-//print("probe 1, sdev %p\n", sdev);
if(sdev = ataprobe(0x170, 0x374, IrqATA1)){
if(head != nil)
tail->next = sdev;
@@ 1606,7 1604,6 @@ atapnp(void)
tail = sdev;
legacy[1] = sdev;
}
-//print("probe 2, sdev %p\n", sdev);
p = nil;
while(p = pcimatch(p, 0, 0)){
@@ 1662,8 1659,6 @@ atapnp(void)
*/
break;
case (0x0646<<16)|0x1095: /* CMD 646 */
-//for(i = 0; i <= 4; i++) print("bar%d: addr %lux size %d\n", i, p->mem[i].bar, p->mem[i].size);
- break;
case (0x0571<<16)|0x1106: /* VIA 82C686 */
case (0x0211<<16)|0x1166: /* ServerWorks IB6566 */
case (0x1230<<16)|0x8086: /* 82371FB (PIIX) */
M pc/trap.c => pc/trap.c +3 -0
@@ 502,6 502,9 @@ syscall(Ureg* ureg)
ret = systab[scallnr](up->s.args);
poperror();
+ }else{
+ /* failure: save the error buffer for errstr */
+ kstrcpy(up->syserror, up->error, sizeof up->syserror);
}
if(up->nerrlab){
print("bad errstack [%d]: %d extra\n", scallnr, up->nerrlab);
M pc/uarti8250.c => pc/uarti8250.c +2 -2
@@ 135,14 135,14 @@ static Uart i8250uart[2] = {
.name = "COM1",
.freq = UartFREQ,
.phys = &i8250physuart,
- .special=0,
+ .special= 0,
.next = &i8250uart[1], },
{ .regs = &i8250ctlr[1],
.name = "COM2",
.freq = UartFREQ,
.phys = &i8250physuart,
- .special=0,
+ .special= 0,
.next = nil, },
};
M pc/vga.c => pc/vga.c +1 -0
@@ 189,6 189,7 @@ vgascreenwin(VGAscr* scr)
curpos = window.min;
screenputs = vgascreenputs;
+
}
/*
A pc/vgavmware.c => pc/vgavmware.c +194 -0
@@ 0,0 1,194 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "io.h"
+#include "../port/error.h"
+
+#define Image IMAGE
+#include <draw.h>
+#include <memdraw.h>
+#include <cursor.h>
+#include "screen.h"
+
+enum {
+ PCIVMWARE = 0x15AD, /* PCI VID */
+
+ VMWARE1 = 0x0710, /* PCI DID */
+ VMWARE2 = 0x0405,
+};
+
+enum {
+ Rid = 0,
+ Renable,
+ Rwidth,
+ Rheight,
+ Rmaxwidth,
+ Rmaxheight,
+ Rdepth,
+ Rbpp,
+ Rpseudocolor,
+ Rrmask,
+ Rgmask,
+ Rbmask,
+ Rbpl,
+ Rfbstart,
+ Rfboffset,
+ Rfbmaxsize,
+ Rfbsize,
+ Rcap,
+ Rmemstart,
+ Rmemsize,
+ Rconfigdone,
+ Rsync,
+ Rbusy,
+ Rguestid,
+ Rcursorid,
+ Rcursorx,
+ Rcursory,
+ Rcursoron,
+ Nreg,
+
+ Rpalette = 1024,
+};
+
+typedef struct Vmware Vmware;
+struct Vmware {
+ ulong mmio;
+ ulong fb;
+
+ ulong ra;
+ ulong rd;
+
+ ulong r[Nreg];
+
+ char chan[32];
+ int depth;
+};
+
+Vmware xvm;
+Vmware *vm=&xvm;
+
+static ulong
+vmrd(Vmware *vm, int i)
+{
+ outl(vm->ra, i);
+ return inl(vm->rd);
+}
+
+static void
+vmwr(Vmware *vm, int i, ulong v)
+{
+ outl(vm->ra, i);
+ outl(vm->rd, v);
+}
+
+static ulong
+vmwarelinear(VGAscr* scr, int* size, int* align)
+{
+ char err[64];
+ ulong aperture, oaperture;
+ int osize, oapsize, wasupamem;
+ Pcidev *p;
+ Physseg seg;
+
+ osize = *size;
+ oaperture = scr->aperture;
+ oapsize = scr->apsize;
+ wasupamem = scr->isupamem;
+
+ p = pcimatch(nil, PCIVMWARE, 0);
+ if(p == nil)
+ error("no vmware card found");
+
+ switch(p->did){
+ default:
+ snprint(err, sizeof err, "unknown vmware id %.4ux", p->did);
+ error(err);
+
+ case VMWARE1:
+ vm->ra = 0x4560;
+ vm->rd = 0x4560+4;
+ break;
+
+ case VMWARE2:
+ vm->ra = p->mem[0].bar&~3;
+ vm->rd = vm->ra + 1;
+ }
+
+ aperture = (ulong)(vmrd(vm, Rfbstart));
+ *size = vmrd(vm, Rfbsize);
+
+ if(wasupamem)
+ upafree(oaperture, oapsize);
+ scr->isupamem = 0;
+
+ aperture = upamalloc(aperture, *size, *align);
+ if(aperture == 0){
+ if(wasupamem && upamalloc(oaperture, oapsize, 0))
+ scr->isupamem = 1;
+ }else
+ scr->isupamem = 1;
+
+ if(oaperture)
+ print("warning (BUG): redefinition of aperture does not change vmwarescreen segment\n");
+ memset(&seg, 0, sizeof(seg));
+ seg.attr = SG_PHYSICAL;
+ seg.name = smalloc(32);
+ snprint(seg.name, 32, "vmwarescreen");
+ seg.pa = aperture;
+ seg.size = osize;
+ addphysseg(&seg);
+ return aperture;
+}
+
+static void
+vmwaredisable(VGAscr*)
+{
+}
+
+static void
+vmwareload(VGAscr*, Cursor*)
+{
+}
+
+static int
+vmwaremove(VGAscr*, Point)
+{
+ return 0;
+}
+
+static void
+vmwareenable(VGAscr*)
+{
+}
+
+static void
+vmwareblank(int)
+{
+}
+
+static void
+vmwaredrawinit(VGAscr*)
+{
+}
+
+VGAdev vgavmwaredev = {
+ "vmware",
+
+ 0,
+ 0,
+ 0,
+ vmwarelinear,
+ vmwaredrawinit,
+};
+
+VGAcur vgavmwarecur = {
+ "vmwarehwgc",
+
+ vmwareenable,
+ vmwaredisable,
+ vmwareload,
+ vmwaremove,
+};
M port/allocb.c => port/allocb.c +4 -5
@@ 62,12 62,11 @@ allocb(int size)
*/
if(up == nil)
panic("allocb without up: %uX\n", getcallerpc(&size));
- if((b = _allocb(size)) == nil)
-{
-xsummary();
-mallocsummary();
+ if((b = _allocb(size)) == nil){
+ xsummary();
+ mallocsummary();
panic("allocb: no memory for %d bytes\n", size);
-}
+ }
setmalloctag(b, getcallerpc(&size));
return b;
M port/chan.c => port/chan.c +28 -16
@@ 237,6 237,7 @@ newchan(void)
c->iounit = 0;
c->umh = 0;
c->uri = 0;
+ c->dri = 0;
c->aux = 0;
c->mchan = 0;
c->mcp = 0;
@@ 546,9 547,9 @@ cunmount(Chan *mnt, Chan *mounted)
Mount *f, **p;
if(mnt->umh) /* should not happen */
- print("cunmount newp extra umh\n");
+ print("cunmount newp extra umh %p has %p\n", mnt, mnt->umh);
if(mounted && mounted->umh)
- print("cunmount old extra umh\n");
+ print("cunmount old extra umh %p has %p\n", mounted, mounted->umh);
pg = up->pgrp;
wlock(&pg->ns);
@@ 771,7 772,7 @@ walk(Chan **cp, char **names, int nnames, int nomount)
runlock(&mh->lock);
nexterror();
}
- for(f = mh->mount; f; f = f->next)
+ for(f = mh->mount->next; f; f = f->next)
if((wq = devtab[f->to->type]->walk(f->to, nil, names, ntry)) != nil)
break;
poperror();
@@ 969,6 970,7 @@ namec(char *aname, int amode, int omode, ulong perm)
Elemlist e;
Rune r;
Mhead *m;
+ char createerr[ERRMAX];
char *name;
name = aname;
@@ 1086,29 1088,36 @@ namec(char *aname, int amode, int omode, ulong perm)
cnameclose(c->name);
c->name = cname;
- if(amode == Aremove){
+ switch(amode){
+ case Aremove:
putmhead(m);
break;
- }
+ case Aopen:
+ case Acreate:
if(c->umh != nil){
print("cunique umh\n");
putmhead(c->umh);
}
- c->umh = m;
+ if(c->qid.type&QTDIR)
+ c->umh = m;
+ else
+ putmhead(m);
- /* save registers else error() in open has wrong value of c saved */
- saveregisters();
+ /* save registers else error() in open has wrong value of c saved */
+ saveregisters();
- if(omode == OEXEC)
- c->flag &= ~CCACHE;
+ if(omode == OEXEC)
+ c->flag &= ~CCACHE;
- c = devtab[c->type]->open(c, omode&~OCEXEC);
+ c = devtab[c->type]->open(c, omode&~OCEXEC);
- if(omode & OCEXEC)
- c->flag |= CCEXEC;
- if(omode & ORCLOSE)
- c->flag |= CRCLOSE;
+ if(omode & OCEXEC)
+ c->flag |= CCEXEC;
+ if(omode & ORCLOSE)
+ c->flag |= CRCLOSE;
+ break;
+ }
break;
case Atodir:
@@ 1222,8 1231,10 @@ if(c->umh != nil){
putmhead(m);
if(omode & OEXCL)
nexterror();
+ /* save error */
+ kstrcpy(createerr, up->error, sizeof createerr);
if(walk(&c, e.elems+e.nelems-1, 1, nomount) < 0)
- nexterror();
+ error(createerr); /* report true error */
omode |= OTRUNC;
goto Open;
}
@@ 1242,6 1253,7 @@ if(c->umh != nil){
kstrcpy(up->genbuf, ".", sizeof up->genbuf);
free(e.name);
free(e.elems);
+
return c;
}
M port/dev.c => port/dev.c +3 -5
@@ 254,20 254,18 @@ devstat(Chan *c, uchar *db, int n, Dirtab *tab, int ntab, Devgen *gen)
long
devdirread(Chan *c, char *d, long n, Dirtab *tab, int ntab, Devgen *gen)
{
- long k, m, dsz;
+ long m, dsz;
struct{
Dir;
char slop[100];
}dir;
- k = c->offset;
- for(m=0; m<n; k++) {
- switch((*gen)(c, nil, tab, ntab, k, &dir)){
+ for(m=0; m<n; c->dri++) {
+ switch((*gen)(c, nil, tab, ntab, c->dri, &dir)){
case -1:
return m;
case 0:
- c->offset++; /* BUG??? (was DIRLEN: skip entry) */
break;
case 1:
M port/devdup.c => port/devdup.c +1 -1
@@ 103,7 103,7 @@ dupread(Chan *c, void *va, long n, vlong offset)
{
char *a = va;
char buf[256];
- int fd, twicefd, m;
+ int fd, twicefd;
Fgrp *f;
if(c->qid.type == QTDIR)
M port/devmnt.c => port/devmnt.c +0 -1
@@ 410,7 410,6 @@ mntwalk(Chan *c, Chan *nc, char **name, int nname)
if(waserror()) {
mntfree(r);
nexterror();
- return nil;
}
r->request.type = Twalk;
r->request.fid = c->fid;
M port/portdat.h => port/portdat.h +3 -1
@@ 155,6 155,7 @@ struct Chan
Chan* umc; /* channel in union; held for union read */
QLock umqlock; /* serialize unionreads */
int uri; /* union read index */
+ int dri; /* devdirread index */
ulong mountid;
Mntcache *mcp; /* Mount cache pointer */
Mnt *mux; /* Mnt for clients using me for messages */
@@ 609,7 610,8 @@ struct Proc
Sargs s; /* address of this is known by db */
int nerrlab;
Label errlab[NERR];
- char error[ERRMAX];
+ char syserror[ERRMAX]; /* last error from a system call */
+ char error[ERRMAX]; /* reason we're unwinding the error stack */
char genbuf[128]; /* buffer used e.g. for last name element from namec */
Chan *slash;
Chan *dot;
M port/proc.c => port/proc.c +2 -1
@@ 339,6 339,7 @@ newproc(void)
p->wired = 0;
p->ureg = 0;
p->error[0] = '\0';
+ p->syserror[0] = '\0';
kstrdup(&p->user, "*nouser");
kstrdup(&p->text, "*notext");
kstrdup(&p->args, "");
@@ 1108,7 1109,7 @@ void
error(char *err)
{
spllo();
- strncpy(up->error, err, ERRMAX);
+ kstrcpy(up->error, err, sizeof up->error);
nexterror();
}
M port/sysfile.c => port/sysfile.c +2 -1
@@ 557,6 557,7 @@ sseek(ulong *arg)
}
*(vlong*)arg[0] = off;
c->uri = 0;
+ c->dri = 0;
cclose(c);
poperror();
}
@@ 783,7 784,7 @@ sysunmount(ulong *arg)
nexterror();
}
validaddr(arg[0], 1, 0);
- cmounted = namec((char*)arg[0], Aopen, OREAD, 0);
+ cmounted = namec((char*)arg[0], Aaccess, OREAD, 0);
poperror();
}
M port/sysproc.c => port/sysproc.c +18 -23
@@ 633,41 633,36 @@ werrstr(char *fmt, ...)
va_end(va);
}
-long
-syserrstr(ulong *arg)
+static long
+generrstr(char *buf, uint nbuf)
{
- char *e, tmp[sizeof up->error];
- uint n;
+ char tmp[sizeof up->syserror];
- n = arg[1];
- if(n > sizeof tmp)
- n = sizeof tmp;
- validaddr(arg[0], n, 1);
- e = (char*)arg[0];
- memmove(tmp, e, n);
+ validaddr((ulong)buf, nbuf, 1);
+ if(nbuf > sizeof tmp)
+ nbuf = sizeof tmp;
+ memmove(tmp, buf, nbuf);
/* make sure it's NUL-terminated */
- tmp[n-1] = '\0';
- memmove(e, up->error, n);
- e[n-1] = '\0';
- memmove(up->error, tmp, n);
+ tmp[nbuf-1] = '\0';
+ memmove(buf, up->syserror, nbuf);
+ buf[nbuf-1] = '\0';
+ memmove(up->syserror, tmp, nbuf);
return 0;
}
+long
+syserrstr(ulong *arg)
+{
+ return generrstr((char*)arg[0], arg[1]);
+}
+
/* compatibility for old binaries */
long
sys_errstr(ulong *arg)
{
- char *e, tmp[64];
-
- validaddr(arg[0], 64, 1);
- e = (char*)arg[0];
- memmove(tmp, e, 64);
- memmove(e, up->error, 64);
- memmove(up->error, tmp, 64);
- return 0;
+ return generrstr((char*)arg[0], 64);
}
-
long
sysnotify(ulong *arg)
{