From 39e8ef7beacede06996f1eda95880e82e8a1764a Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 25 Aug 1992 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1992-08-25 --- boot/local.c | 2 +- pc/devconfig.c | 215 ++++++++++++++++++++++++++++++++++++++++++++++++ pc/fns.h | 1 + pc/kbd.c | 19 ++++- port/chan.c | 12 ++- port/devcons.c | 21 ++--- port/devdup.c | 2 +- port/devmnt.c | 71 +++++----------- port/devmux.c | 2 +- port/devscsi.c | 48 +++++++++++ port/devsrv.c | 13 +-- port/devwren.c | 5 +- port/fault.c | 6 -- port/portdat.h | 4 +- port/portfns.h | 4 +- port/stsplice.c | 2 +- port/swap.c | 3 - port/sysfile.c | 138 ++++++++++++++++++++++--------- ss/div.c | 134 ------------------------------ 19 files changed, 431 insertions(+), 271 deletions(-) create mode 100644 pc/devconfig.c delete mode 100644 ss/div.c diff --git a/boot/local.c b/boot/local.c index 79fb25f2c987271a8cb0f51ef9cdf2cbe86935dc..ef13f8b2d88e226239bbf7484d5339e8a69fbc2f 100644 --- a/boot/local.c +++ b/boot/local.c @@ -7,7 +7,7 @@ static char *disk; void configlocal(Method *mp) { - disk = mp->arg; + disk = *sys ? sys : mp->arg; USED(mp); } diff --git a/pc/devconfig.c b/pc/devconfig.c new file mode 100644 index 0000000000000000000000000000000000000000..6727693f38ef96c17aaae6a6c721f9564659038a --- /dev/null +++ b/pc/devconfig.c @@ -0,0 +1,215 @@ +#include "u.h" +#include "../port/lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "io.h" +#include "../port/error.h" + +#include +#include +#include "devtab.h" +#include "vga.h" + +/* + * Driver for various VGA cards + */ + +char monitor[NAMELEN]; /* monitor name and type */ +char vgacard[NAMELEN]; /* vga card type */ +struct screeninfo { + int maxx, maxy; /* current bits per screen */ + int packed; /* 0=planar, 1=packed */ + int interlaced; /* != 0 if interlaced */ +} screeninfo; + +enum { + Qdir= 0, + Qvgamonitor= 1, + Qvgasize= 2, + Qvgatype= 3, + Qvgaport= 4, + Qvgamem= 5, + Qmouse= 6, + Nvga= 6, +}; + +Dirtab vgadir[]={ + "mouseconf", {Qmouse}, 0, 0666, + "vgamonitor", {Qvgamonitor}, 0, 0666, + "vgatype", {Qvgatype}, 0, 0666, + "vgasize", {Qvgasize}, 0, 0666, + "vgaport", {Qvgaport}, 0, 0666, + "vgamem", {Qvgamem}, 0, 0666, +}; + +/* a routine from ../port/devcons.c */ +extern int readstr(ulong, char *, ulong, char *); + +void +configsetup(void) { +} + +void +configreset(void) { + strcpy(monitor, "generic"); + strcpy(vgacard, "generic"); + screeninfo.maxx = 640; + screeninfo.maxy = 480; + screeninfo.packed = 0; + screeninfo.interlaced = 0; +} + +void +configinit(void) +{ +} + +Chan* +configattach(char *upec) +{ + return devattach('v', upec); +} + +Chan* +configclone(Chan *c, Chan *nc) +{ + return devclone(c, nc); +} + +int +configwalk(Chan *c, char *name) +{ + return devwalk(c, name, vgadir, Nvga, devgen); +} + +void +configstat(Chan *c, char *dp) +{ + devstat(c, dp, vgadir, Nvga, devgen); +} + +Chan* +configopen(Chan *c, int omode) +{ + return devopen(c, omode, vgadir, Nvga, devgen); +} + +void +configcreate(Chan *c, char *name, int omode, ulong perm) +{ + USED(c, name, omode, perm); + error(Eperm); +} + +void +configclose(Chan *c) +{ + USED(c); +} + +long +configread(Chan *c, void *buf, long n, ulong offset) +{ + char obuf[60]; + int port; + uchar *cp = buf; + + switch(c->qid.path&~CHDIR){ + case Qdir: + return devdirread(c, buf, n, vgadir, Nvga, devgen); + case Qvgamonitor: + return readstr(offset, buf, n, monitor); + case Qvgatype: + return readstr(offset, buf, n, vgacard); + case Qvgasize: + sprint(obuf, "%d %d", + gscreen.r.max.x, gscreen.r.max.y); + return readstr(offset, buf, n, obuf); + case Qvgaport: + if (offset + n >= 0x8000) + error(Ebadarg); + for (port=offset; port 0x10000) + return 0; + if (offset + n > 0x10000) + n = 0x10000 - offset; + memmove(cp, (void *)(SCREENMEM+offset), n); + return n; + } + error(Eperm); + return 0; +} + +long +configwrite(Chan *c, void *buf, long n, ulong offset) +{ + char cbuf[20], *cp; + int port, maxx, maxy; + + switch(c->qid.path&~CHDIR){ + case Qdir: + error(Eperm); + case Qvgamonitor: + error(Eperm); + case Qvgatype: + error(Eperm); + case Qvgasize: + if(offset != 0) + error(Ebadarg); + if(n >= sizeof(cbuf)) + n = sizeof(cbuf) - 1; + memmove(cbuf, buf, n); + cbuf[n] = 0; + cp = cbuf; + maxx = strtoul(cp, &cp, 0); + maxy = strtoul(cp, &cp, 0); + if (maxx == 0 || maxy == 0 || + maxx > 1280 || maxy > 1024) + error(Ebadarg); + setscreen(maxx, maxy, 1); + return n; + case Qvgaport: + cp = buf; + if (offset + n >= 0x8000) + error(Ebadarg); + for (port=offset; port 0x10000) + error(Ebadarg); + memmove((void *)(SCREENMEM+offset), buf, n); + return n; + case Qmouse: + if(n >= sizeof(cbuf)) + n = sizeof(cbuf) - 1; + memmove(cbuf, buf, n); + cbuf[n] = 0; + if(strncmp("accelerated", cbuf, 11) == 0) + mouseaccelerate(1); + else if(strncmp("linear", cbuf, 6) == 0) + mouseaccelerate(0); + return n; + } + error(Eperm); + return 0; +} + +void +configremove(Chan *c) +{ + USED(c); + error(Eperm); +} + +void +configwstat(Chan *c, char *dp) +{ + USED(c, dp); + error(Eperm); +} diff --git a/pc/fns.h b/pc/fns.h index e8fd25ec085b302bd0a246c83159ebdbce5f0c3d..c1a00cb091aabb4e66b64dc036205c1c8d9ff771 100644 --- a/pc/fns.h +++ b/pc/fns.h @@ -37,6 +37,7 @@ void ksetpcinfo(void); void mathinit(void); void mmuinit(void); int modem(int); +void mouseaccelerate(int); void outb(int, int); void outss(int, void*, int); void pmubuzz(int, int); diff --git a/pc/kbd.c b/pc/kbd.c index b20eb00238a4e25a4d76b27af85b429e8ed9c9a9..15a4319caa260adad4167864cf4318dcefd6f754 100644 --- a/pc/kbd.c +++ b/pc/kbd.c @@ -214,7 +214,7 @@ kbdinit(void) print("can't initialize mouse\n"); /* turn on mouse acceleration */ - mousecmd(0xE7); + mouseaccelerate(0); break; case At: /* enable kbd xfers and interrupts */ @@ -229,6 +229,23 @@ kbdinit(void) } } +/* + * turn mouse acceleration on/off + */ +void +mouseaccelerate(int on) +{ + + switch(machtype){ + case Attnsx: + if(on) + mousecmd(0xE7); + else + mousecmd(0xE6); + break; + } +} + /* * mouse message is three bytes * diff --git a/port/chan.c b/port/chan.c index 2cca409615c4258bf06fcc9810738dbe1a0636a8..17527d89ad83692b92d25d9fbbf06e9461c30f3d 100644 --- a/port/chan.c +++ b/port/chan.c @@ -306,12 +306,13 @@ undomount(Chan *c) he = &pg->mnthash[MNTHASH]; for(h = pg->mnthash; h < he; h++) { for(f = *h; f; f = f->hash) { - for(t = f->mount; t; t = t->next) + for(t = f->mount; t; t = t->next) { if(eqchan(c, t->to, 1)) { close(c); c = clone(t->head->from, 0); break; } + } } } poperror(); @@ -452,13 +453,15 @@ namec(char *name, int amode, int omode, ulong perm) elem = u->elem; mntok = 1; isdot = 0; - if(name[0] == '/'){ + if(name[0] == '/') { c = clone(u->slash, 0); /* * Skip leading slashes. */ name = skipslash(name); - }else if(name[0] == '#'){ + } + else + if(name[0] == '#') { mntok = 0; if(name[1]=='M') error(Enonexist); @@ -472,7 +475,8 @@ namec(char *name, int amode, int omode, ulong perm) }else name = nextelem(name, elem); c = (*devtab[t].attach)(elem); - }else{ + } + else { c = clone(u->dot, 0); name = skipslash(name); /* eat leading ./ */ if(*name == 0) diff --git a/port/devcons.c b/port/devcons.c index 2b5269331f6aea73d23c3bd4d496682a14ea90b5..b0faa2527c92c6c840010bc7385ca35da7cefae8 100644 --- a/port/devcons.c +++ b/port/devcons.c @@ -188,15 +188,13 @@ 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->wrl); - if(waserror()){ - qunlock(&c->wrl); - return 0; - } + (*devtab[c->type].write)(c, buf, n, c->offset); + + lock(c); c->offset += n; - qunlock(&c->wrl); - poperror(); + unlock(c); + return n; } @@ -887,8 +885,9 @@ conswrite(Chan *c, void *va, long n, ulong offset) error(Egreg); memmove(buf, va, n); /* so we can NUL-terminate */ buf[n] = 0; + /* start a pager if not already started */ if(strncmp(buf, "start", 5) == 0){ - kickpager(); /* start a pager if not already started */ + kickpager(); break; } if(cpuserver && strcmp(u->p->user, eve) != 0) @@ -896,7 +895,7 @@ conswrite(Chan *c, void *va, long n, ulong offset) if(buf[0]<'0' || '9'offset = 0; return c; } - fdtochan(c->qid.path, openmode(omode), 0); /* error check only */ + fdtochan(c->qid.path, openmode(omode), 0, 0); /* error check only */ f = u->p->fgrp->fd[c->qid.path]; close(c); incref(f); diff --git a/port/devmnt.c b/port/devmnt.c index 274eb905c18aad964508b5e602bc3628b2e34fa6..c77d3f0900398282c173e90ca8e3e40cdd2234c9 100644 --- a/port/devmnt.c +++ b/port/devmnt.c @@ -48,23 +48,23 @@ struct Mntalloc #define MAXRPC (MAXFDATA+MAXMSG) #define limit(n, max) (n > max ? max : n) -Chan *mattach(Mnt*, char*, char*); -Mntrpc *mntralloc(void); -void mntfree(Mntrpc*); -int rpcattn(Mntrpc*); -void mountrpc(Mnt*, Mntrpc*); -void mountio(Mnt*, Mntrpc*); -Mnt *mntchk(Chan*); -void mountmux(Mnt*, Mntrpc*); -long mntrdwr(int , Chan*, void*,long , ulong); -int mntflush(Mnt*, Mntrpc*); -void mntqrm(Mnt*, Mntrpc*); +Chan* mattach(Mnt*, char*, char*); +void mntauth(Mnt *, Mntrpc *, char *, ushort); +Mnt* mntchk(Chan*); void mntdirfix(uchar*, Chan*); -void mntgate(Mnt*); -void mntrpcread(Mnt*, Mntrpc*); void mntdoclunk(Mnt *, Mntrpc *); -void mntauth(Mnt *, Mntrpc *, char *, ushort); +int mntflush(Mnt*, Mntrpc*); +void mntfree(Mntrpc*); +void mntgate(Mnt*); void mntpntfree(Mnt*); +void mntqrm(Mnt*, Mntrpc*); +Mntrpc* mntralloc(void); +long mntrdwr(int , Chan*, void*,long , ulong); +void mntrpcread(Mnt*, Mntrpc*); +void mountio(Mnt*, Mntrpc*); +void mountmux(Mnt*, Mntrpc*); +void mountrpc(Mnt*, Mntrpc*); +int rpcattn(Mntrpc*); enum { @@ -203,9 +203,9 @@ mattach(Mnt *m, char *spec, char *serv) void mntauth(Mnt *m, Mntrpc *f, char *serv, ushort fid) { + int i; Mntrpc *r; uchar chal[AUTHLEN]; - int i; r = mntralloc(); if(waserror()) { @@ -493,8 +493,8 @@ mntrdwr(int type, Chan *c, void *buf, long n, ulong offset) { Mnt *m; Mntrpc *r; - ulong cnt, nr; char *uba; + ulong cnt, nr; m = mntchk(c); uba = buf; @@ -561,23 +561,12 @@ mountio(Mnt *m, Mntrpc *r) /* Transmit a file system rpc */ n = convS2M(&r->request, r->rpc); if(waserror()) { - if(!m->mux) - qunlock(&m->c->wrl); if(mntflush(m, r) == 0) nexterror(); } else { - - if(m->mux) { - if((*devtab[m->c->type].write)(m->c, r->rpc, n, 0) != n) - error(Emountrpc); - } - else { - qlock(&m->c->wrl); - if((*devtab[m->c->type].write)(m->c, r->rpc, n, 0) != n) - error(Emountrpc); - qunlock(&m->c->wrl); - } + if((*devtab[m->c->type].write)(m->c, r->rpc, n, 0) != n) + error(Emountrpc); poperror(); } if(m->mux) { @@ -618,8 +607,6 @@ mntrpcread(Mnt *m, Mntrpc *r) for(;;) { if(waserror()) { - if(!m->mux) - qunlock(&m->c->rdl); if(mntflush(m, r) == 0) { if(m->mux == 0) mntgate(m); @@ -629,13 +616,7 @@ mntrpcread(Mnt *m, Mntrpc *r) } r->reply.type = 0; r->reply.tag = 0; - if(m->mux) - n = (*devtab[m->c->type].read)(m->c, r->rpc, MAXRPC, 0); - else { - qlock(&m->c->rdl); - n = (*devtab[m->c->type].read)(m->c, r->rpc, MAXRPC, 0); - qunlock(&m->c->rdl); - } + n = (*devtab[m->c->type].read)(m->c, r->rpc, MAXRPC, 0); poperror(); if(n == 0) continue; @@ -669,8 +650,8 @@ mntgate(Mnt *m) void mountmux(Mnt *m, Mntrpc *r) { - Mntrpc **l, *q; char *dp; + Mntrpc **l, *q; lock(m); l = &m->queue; @@ -698,8 +679,8 @@ mountmux(Mnt *m, Mntrpc *r) int mntflush(Mnt *m, Mntrpc *r) { - Fcall flush; int n; + Fcall flush; lock(m); r->flushtag = m->flushtag++; @@ -714,20 +695,12 @@ mntflush(Mnt *m, Mntrpc *r) n = convS2M(&flush, r->flush); if(waserror()) { - if(!m->mux) - qunlock(&m->c->wrl); if(strcmp(u->error, Eintr) == 0) return 1; mntqrm(m, r); return 0; } - if(m->mux) - (*devtab[m->c->type].write)(m->c, r->flush, n, 0); - else { - qlock(&m->c->wrl); - (*devtab[m->c->type].write)(m->c, r->flush, n, 0); - qunlock(&m->c->wrl); - } + (*devtab[m->c->type].write)(m->c, r->flush, n, 0); poperror(); return 1; } diff --git a/port/devmux.c b/port/devmux.c index 5f56cc9f6f3c34ed4b4364e91c80c2b61ca552f1..1eb22ead454c8428ca2a64c3131086a2693dfb4d 100644 --- a/port/devmux.c +++ b/port/devmux.c @@ -465,7 +465,7 @@ muxwrite(Chan *c, void *va, long n, ulong offset) memmove(buf, va, n); /* so we can NUL-terminate */ buf[n] = 0; fd = strtoul(buf, 0, 0); - fdtochan(fd, -1, 0); /* error check */ + fdtochan(fd, -1, 0, 0); /* error check */ m->c = u->p->fgrp->fd[fd]; incref(m->c); return n; diff --git a/port/devscsi.c b/port/devscsi.c index c359bdbde2d47962b6eaac8f1360daf5f079e504..be4d4b682f5398a1728d79ccb9cbec5d1fc90339 100644 --- a/port/devscsi.c +++ b/port/devscsi.c @@ -326,6 +326,7 @@ scsicmd(int dev, int cmdbyte, Scsibuf *b, long size) cmd->cmdblk[2] = 1; /* fall through */ case ScsiExtsens: + case ScsiInquiry: cmd->cmdblk[4] = size; break; case ScsiGetcap: @@ -406,6 +407,30 @@ scsicap(int dev, void *p) return status&0xff; } +int +scsiinquiry(int dev, void *p, int size) +{ + Scsi *cmd; + int status; + + cmd = scsicmd(dev, ScsiInquiry, scsibuf(), size); + if(waserror()){ + scsifree(cmd->b); + qunlock(cmd); + nexterror(); + } + status = scsiexec(cmd, ScsiIn); + memmove(p, cmd->data.base, size); + poperror(); + scsifree(cmd->b); + qunlock(cmd); + if((status&0xff00) != 0x6000) + error(Eio); + if(status & 0xFF) + scsisense(dev, p); + return status&0xff; +} + int scsiwp(int dev) { @@ -428,6 +453,29 @@ scsiwp(int dev) return r; } +int +scsimodesense(int dev, int page, void *p, int size) +{ + Scsi *cmd; + int status; + + cmd = scsicmd(dev, ScsiModesense, scsibuf(), size); + cmd->cmdblk[2] = page; + if(waserror()){ + scsifree(cmd->b); + qunlock(cmd); + nexterror(); + } + status = scsiexec(cmd, ScsiIn); + memmove(p, cmd->data.base, size); + poperror(); + scsifree(cmd->b); + qunlock(cmd); + if ((status&0xffff) != 0x6000) + error(Eio); + return status&0xff; +} + int scsibread(int dev, Scsibuf *b, long n, long blocksize, long blockno) { diff --git a/port/devsrv.c b/port/devsrv.c index 74cdb6e77a24f1f41f42d9144e1374d8c8111cf9..ae0a919808cd633d55f3e067c33a73bb259f3ffc 100644 --- a/port/devsrv.c +++ b/port/devsrv.c @@ -207,7 +207,6 @@ long srvwrite(Chan *c, void *va, long n, ulong offset) { Srv *sp; - Fgrp *f; Chan *c1; int fd; char buf[32]; @@ -219,17 +218,7 @@ srvwrite(Chan *c, void *va, long n, ulong offset) buf[n] = 0; fd = strtoul(buf, 0, 0); - f = u->p->fgrp; - lock(f); - if(waserror()){ - unlock(f); - nexterror(); - } - fdtochan(fd, -1, 0); /* error check only */ - c1 = f->fd[fd]; - incref(c1); - unlock(f); - poperror(); + c1 = fdtochan(fd, -1, 0, 1); /* error check only */ qlock(&srvlk); if(waserror()) { diff --git a/port/devwren.c b/port/devwren.c index f822f81cc7d9000d9ad74b5021cfc59f1b12092b..054d9e0ee685238744912403f7b97beb7cce2e72 100644 --- a/port/devwren.c +++ b/port/devwren.c @@ -261,7 +261,7 @@ wrenpart(int dev) { Drive *dp; Partition *pp; - uchar buf[32]; + uchar buf[128]; Scsibuf *b; char *rawpart, *line[Npart+1], *field[3]; ulong n; @@ -294,6 +294,9 @@ wrenpart(int dev) pp->start = dp->p[0].end - 1; pp->end = dp->p[0].end; + scsiinquiry(dev, buf, sizeof buf); + if(memcmp(&buf[8], "INSITE I325VM *F", 24) == 0) + scsimodesense(dev, 0x2e, buf, 0x2a); /* * read partition table from disk, null terminate */ diff --git a/port/fault.c b/port/fault.c index de1b4916a4a08ef28ba66b9f132475763694a7a6..43734a9c4bd9e9b70ca80cba4424cac333f8032c 100644 --- a/port/fault.c +++ b/port/fault.c @@ -185,11 +185,9 @@ pio(Segment *s, ulong addr, ulong soff, Page **p) if(loadrec == 0) { /* This is demand load */ c = s->image->c; - qlock(&c->rdl); while(waserror()) { if(strcmp(u->error, Eintr) == 0) continue; - qunlock(&c->rdl); kunmap(k); putpage(new); faulterror("sys: demand load I/O error"); @@ -207,7 +205,6 @@ pio(Segment *s, ulong addr, ulong soff, Page **p) poperror(); kunmap(k); - qunlock(&c->rdl); qlock(&s->lk); if(*p == 0) { /* Someone may have got there first */ new->daddr = daddr; @@ -219,10 +216,8 @@ pio(Segment *s, ulong addr, ulong soff, Page **p) } else { /* This is paged out */ c = swapimage.c; - qlock(&c->rdl); if(waserror()) { - qunlock(&c->rdl); kunmap(k); putpage(new); qlock(&s->lk); @@ -236,7 +231,6 @@ pio(Segment *s, ulong addr, ulong soff, Page **p) poperror(); kunmap(k); - qunlock(&c->rdl); qlock(&s->lk); if(pagedout(*p)) { diff --git a/port/portdat.h b/port/portdat.h index 16b48522045b270c8e62bd006bf8c5e2fb3b33f2..eb5e72f2fd10f34f29b744200095be86c28fe1ee 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -149,9 +149,6 @@ enum struct Chan { - QLock rdl; /* read access */ - QLock wrl; /* write access */ - Lock offl; /* offset access */ Ref; union{ Chan *next; /* allocation */ @@ -231,6 +228,7 @@ enum { ScsiTestunit = 0x00, ScsiExtsens = 0x03, + ScsiInquiry = 0x12, ScsiModesense = 0x1a, ScsiGetcap = 0x25, ScsiRead = 0x08, diff --git a/port/portfns.h b/port/portfns.h index 84632b6bb1d32ec1949d37569156ef6d488591a4..a4f1816733445b36ed231f4279da1f0d0bb34e0e 100644 --- a/port/portfns.h +++ b/port/portfns.h @@ -60,7 +60,7 @@ void exit(int); Block* expandb(Block*, int); int fault(ulong, int); void fdclose(int, int); -Chan* fdtochan(int, int, int); +Chan* fdtochan(int, int, int, int); int fixfault(Segment*, ulong, int, int); void flowctl(Queue*, Block*); void flushmmu(void); @@ -205,6 +205,8 @@ int scsicap(int, void*); Scsi* scsicmd(int, int, Scsibuf*, long); int scsiexec(Scsi*, int); void scsifree(Scsibuf*); +int scsiinquiry(int, void*, int); +int scsimodesense(int, int, void*, int); int scsiready(int); int scsisense(int, void*); int scsiwp(int); diff --git a/port/stsplice.c b/port/stsplice.c index a55dd90ccfbe093150abeb1ccd99a962c0eb3770..f5de37dabd88805f33f1ebcb276d12f46f73a01a 100644 --- a/port/stsplice.c +++ b/port/stsplice.c @@ -61,7 +61,7 @@ spliceoput(Queue *q, Block *bp) freeb(bp); if(RD(q)->ptr) error("stream already spliced"); - c = fdtochan(fd, ORDWR, 0); + c = fdtochan(fd, ORDWR, 0, 0); s = c->stream; if(s == 0) error("splice attempt on non-stream"); diff --git a/port/swap.c b/port/swap.c index b47aa17738e839da007dda42aeb2c8a6612b01cc..ad001b4165a82a897be9c337c86254813de06f0e 100644 --- a/port/swap.c +++ b/port/swap.c @@ -292,7 +292,6 @@ executeio(void) k = kmap(out); kaddr = (char*)VA(k); - qlock(&c->wrl); if(waserror()) panic("executeio: page out I/O error"); @@ -301,7 +300,6 @@ executeio(void) if(n != BY2PG) nexterror(); - qunlock(&c->wrl); kunmap(k); poperror(); @@ -332,4 +330,3 @@ setswapchan(Chan *c) incref(c); swapimage.c = c; } - diff --git a/port/sysfile.c b/port/sysfile.c index 099502b6edcff9c5abc2d0f2035959369e37b9b7..fecd25f68e178fb41a8bb0a0bf0e8fccd8aee641 100644 --- a/port/sysfile.c +++ b/port/sysfile.c @@ -30,21 +30,44 @@ newfd(Chan *c) } Chan* -fdtochan(int fd, int mode, int chkmnt) +fdtochan(int fd, int mode, int chkmnt, int iref) { Chan *c; + Fgrp *f; c = 0; - if(fd<0 || NFD<=fd || (c = u->p->fgrp->fd[fd])==0) + f = u->p->fgrp; + + lock(f); + if(fd<0 || NFD<=fd || (c = f->fd[fd])==0) { + unlock(f); error(Ebadfd); - if(chkmnt && (c->flag&CMSG)) + } + if(iref) + incref(c); + unlock(f); + + if(chkmnt && (c->flag&CMSG)) { + if(iref) + close(c); error(Ebadusefd); + } + if(mode<0 || c->mode==ORDWR) return c; - if((mode&OTRUNC) && c->mode==OREAD) + + if((mode&OTRUNC) && c->mode==OREAD) { + if(iref) + close(c); error(Ebadusefd); - if((mode&~OTRUNC) != c->mode) + } + + if((mode&~OTRUNC) != c->mode) { + if(iref) + close(c); error(Ebadusefd); + } + return c; } @@ -109,16 +132,17 @@ sysdup(ulong *arg) /* * Close after dup'ing, so date > #d/1 works */ - c = fdtochan(arg[0], -1, 0); + c = fdtochan(arg[0], -1, 0, 1); fd = arg[1]; if(fd != -1){ - if(fd<0 || NFD<=fd) + if(fd<0 || NFD<=fd) { + close(c); error(Ebadfd); - + } lock(f); if(fd > f->maxfd) f->maxfd = fd; - incref(c); + oc = f->fd[fd]; f->fd[fd] = c; unlock(f); @@ -129,7 +153,6 @@ sysdup(ulong *arg) close(c); nexterror(); } - incref(c); fd = newfd(c); poperror(); } @@ -188,7 +211,7 @@ fdclose(int fd, int flag) long sysclose(ulong *arg) { - fdtochan(arg[0], -1, 0); + fdtochan(arg[0], -1, 0, 0); fdclose(arg[0], 0); return 0; @@ -252,32 +275,38 @@ unionread(Chan *c, void *va, long n) long sysread(ulong *arg) { - Chan *c; + int dir; long n; + Chan *c; - c = fdtochan(arg[0], OREAD, 1); validaddr(arg[1], arg[2], 1); - qlock(&c->rdl); - - if(waserror()){ - qunlock(&c->rdl); + c = fdtochan(arg[0], OREAD, 1, 1); + if(waserror()) { + close(c); nexterror(); } + n = arg[2]; - if(c->qid.path & CHDIR){ + dir = c->qid.path&CHDIR; + + if(dir) { n -= n%DIRLEN; if(c->offset%DIRLEN || n==0) error(Etoosmall); } - if((c->qid.path&CHDIR) && c->mnt) + + if(dir && c->mnt) n = unionread(c, (void*)arg[1], n); else n = (*devtab[c->type].read)(c, (void*)arg[1], n, c->offset); - qunlock(&c->rdl); - poperror(); - lock(&c->offl); + + lock(c); c->offset += n; - unlock(&c->offl); + unlock(c); + + poperror(); + close(c); + return n; } @@ -287,22 +316,25 @@ syswrite(ulong *arg) Chan *c; long n; - c = fdtochan(arg[0], OWRITE, 1); validaddr(arg[1], arg[2], 0); - qlock(&c->wrl); - - if(waserror()){ - qunlock(&c->wrl); + c = fdtochan(arg[0], OWRITE, 1, 1); + if(waserror()) { + close(c); nexterror(); } + if(c->qid.path & CHDIR) error(Eisdir); + n = (*devtab[c->type].write)(c, (void*)arg[1], arg[2], c->offset); - qunlock(&c->wrl); - poperror(); - lock(&c->offl); + + lock(c); c->offset += n; - unlock(&c->offl); + unlock(c); + + poperror(); + close(c); + return n; } @@ -314,11 +346,13 @@ sysseek(ulong *arg) Dir dir; long off; - c = fdtochan(arg[0], -1, 1); + c = fdtochan(arg[0], -1, 1, 0); if(c->qid.path & CHDIR) error(Eisdir); + if(devchar[c->type] == '|') error(Eisstream); + off = 0; switch(arg[2]){ case 0: @@ -326,10 +360,10 @@ sysseek(ulong *arg) break; case 1: - lock(&c->offl); /* lock for read/write update */ + lock(c); /* lock for read/write update */ c->offset += (long)arg[1]; off = c->offset; - unlock(&c->offl); + unlock(c); break; case 2: @@ -349,8 +383,14 @@ sysfstat(ulong *arg) validaddr(arg[1], DIRLEN, 1); evenaddr(arg[1]); - c = fdtochan(arg[0], -1, 0); + c = fdtochan(arg[0], -1, 0, 1); + if(waserror()) { + close(c); + nexterror(); + } (*devtab[c->type].stat)(c, (char*)arg[1]); + poperror(); + close(c); return 0; } @@ -388,7 +428,7 @@ syschdir(ulong *arg) long bindmount(ulong *arg, int ismount) { - Chan *c0, *c1; + Chan *c0, *c1, *bc; ulong flag; long ret; int fd; @@ -403,18 +443,30 @@ bindmount(ulong *arg, int ismount) if(flag>MMASK || (flag&MORDER)==(MBEFORE|MAFTER)) error(Ebadarg); if(ismount){ - bogus.chan = fdtochan(fd, 2, 0); + bc = fdtochan(fd, 2, 0, 1); + if(waserror()) { + close(bc); + nexterror(); + } + bogus.chan = bc; + validaddr(arg[3], 1, 0); if(vmemchr((char*)arg[3], '\0', NAMELEN) == 0) error(Ebadarg); + bogus.spec = (char*)arg[3]; validaddr(arg[4], 1, 0); if(vmemchr((char*)arg[4], '\0', NAMELEN) == 0) error(Ebadarg); + bogus.serv = (char*)arg[4]; ret = devno('M', 0); c0 = (*devtab[ret].attach)((char*)&bogus); - }else{ + + poperror(); + close(bc); + } + else { validaddr(arg[0], 1, 0); c0 = namec((char*)arg[0], Aaccess, 0, 0); } @@ -556,7 +608,13 @@ sysfwstat(ulong *arg) validaddr(arg[1], DIRLEN, 0); nameok((char*)arg[1]); - c = fdtochan(arg[0], -1, 1); + c = fdtochan(arg[0], -1, 1, 1); + if(waserror()) { + close(c); + nexterror(); + } (*devtab[c->type].wstat)(c, (char*)arg[1]); + poperror(); + close(c); return 0; } diff --git a/ss/div.c b/ss/div.c deleted file mode 100644 index ea5e28e17681d4d6f6b4637fe22edd453c486f32..0000000000000000000000000000000000000000 --- a/ss/div.c +++ /dev/null @@ -1,134 +0,0 @@ -#include - -#define W 32 - -ulong -_udiv(ulong dividend, ulong divisor) -{ - long R; /* partial remainder */ - ulong Q; /* partial quotient */ - int iter; - ulong logQ, m; - - m = (1<<(W-1))+1; - if(dividend < m) - m = dividend; - for(logQ=0; logQ= m) - break; - - R = dividend; - Q = 0; - for(iter=logQ; iter>=0; iter--){ - if(R >= 0){ - R -= divisor<= m) - break; - - R = dividend; - for(iter=logQ; iter>=0; iter--){ - if(R >= 0) - R -= divisor<=0 && divisor>=0) - return _udiv(dividend, divisor); - if(dividend<0 && divisor<0) - return _udiv(-dividend, -divisor); - if(dividend < 0) - return -_udiv(-dividend, divisor); - return -_udiv(dividend, -divisor); -} - -ulong -_rem(long dividend, long divisor) -{ - if(dividend>=0 && divisor>=0) - return _urem(dividend, divisor); - if(dividend<0 && divisor<0) - return _urem(-dividend, -divisor); - if(dividend < 0) - return -_urem(-dividend, divisor); - return -_urem(dividend, -divisor); -} - -long -_asmul(long *a, long b) -{ - long c; - - c = *a * b; - *a = c; - return c; -} - -long -_asdiv(long *a, long b) -{ - long c; - - c = *a / b; - *a = c; - return c; -} - -long -_asrem(long *a, long b) -{ - long c; - - c = *a % b; - *a = c; - return c; -} - -ulong -_asudiv(ulong *a, ulong b) -{ - ulong c; - - c = *a / b; - *a = c; - return c; -} - -ulong -_asurem(ulong *a, ulong b) -{ - ulong c; - - c = *a % b; - *a = c; - return c; -}