From 9542dc66231c8212f79e5ff609418eb15d40f3ea Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sat, 17 Nov 2001 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2001-11-17 --- alphapc/devfloppy.c | 2 +- alphapc/devvga.c | 2 +- bitsy/devpenmouse.c | 2 +- bitsy/devuda1341.c | 2 +- boot/boot.c | 2 +- boot/bootcache.c | 2 +- ip/arp.c | 2 +- ip/icmp.c | 28 +++++++++++++-- ip/ip.c | 85 +++++++++++++++++++++++++++++++++++++++++++-- ip/ip.h | 3 ++ ip/ipifc.c | 7 +++- ip/netlog.c | 2 +- ip/tcp.c | 57 ++++++++++++++++++++---------- pc/devfloppy.c | 2 +- pc/devpccard.c | 2 +- pc/devusb.c | 4 +-- pc/devvga.c | 2 +- pc/vgamach64xx.c | 2 +- port/devaudio.c | 2 +- port/devdraw.c | 2 +- port/devmouse.c | 2 +- port/devproc.c | 15 ++++---- port/devsd.c | 4 +-- port/devuart.c | 2 +- port/parse.c | 41 ++++++++++++++++++---- port/portdat.h | 8 +++-- port/proc.c | 1 + port/sysproc.c | 1 + 28 files changed, 227 insertions(+), 59 deletions(-) diff --git a/alphapc/devfloppy.c b/alphapc/devfloppy.c index 1195ebb83b36eb611a45fff318b3dffe2902bbc0..96ac918495832820763bdedcb98407e5b184b8c5 100644 --- a/alphapc/devfloppy.c +++ b/alphapc/devfloppy.c @@ -911,7 +911,7 @@ floppyformat(FDrive *dp, char *params) /* * set the type */ - if(getfields(params, f, 3, 1, " ") > 1){ + if(tokenize(params, f, 3) > 1){ for(t = floppytype; t < &floppytype[nelem(floppytype)]; t++){ if(strcmp(f[1], t->name)==0 && t->dt==dp->dt){ dp->t = t; diff --git a/alphapc/devvga.c b/alphapc/devvga.c index 88ebe5d0e2154c7946413bcebca59858c3b9c46c..b21b8b075f8ee1d47e4d848db674e8f7875c7a9d 100644 --- a/alphapc/devvga.c +++ b/alphapc/devvga.c @@ -173,7 +173,7 @@ vgactl(char* a) extern VGAcur *vgacur[]; Rectangle r; - n = getfields(a, field, nelem(field), 1, " "); + n = tokenize(a, field, nelem(field)); if(n < 1) error(Ebadarg); diff --git a/bitsy/devpenmouse.c b/bitsy/devpenmouse.c index 143cd14b69becc0993c699bec54c23afcd5cafef..3d2a738c8b30049334159f20f6c4d1b1ecbad9ca 100644 --- a/bitsy/devpenmouse.c +++ b/bitsy/devpenmouse.c @@ -341,7 +341,7 @@ penmousewrite(Chan *c, void *va, long n, vlong) buf[n-1] = 0; else buf[n] = 0; - nf = getfields(buf, field, 5, 1, " "); + nf = tokenize(buf, field, 5); if(strcmp(field[0], "swap") == 0){ if(mouseswap) setbuttonmap("123"); diff --git a/bitsy/devuda1341.c b/bitsy/devuda1341.c index 0b9fc6034095ec4f6484e95102a98aba862ffe50..fc88c7daf365f59bde20cb306790c0be28944f2e 100644 --- a/bitsy/devuda1341.c +++ b/bitsy/devuda1341.c @@ -1270,7 +1270,7 @@ audiowrite(Chan *c, void *vp, long n, vlong) memmove(buf, p, n); buf[n] = '\0'; - nf = getfields(buf, field, Ncmd, 1, " \t\n"); + nf = tokenize(buf, field, Ncmd); for(i = 0; i < nf; i++){ /* * a number is volume diff --git a/boot/boot.c b/boot/boot.c index 4954faa0a5676fdbd599a39237cf653cd1dd468c..497f42923194835c1f6968dc25094c659df3691d 100644 --- a/boot/boot.c +++ b/boot/boot.c @@ -232,7 +232,7 @@ rootserver(char *arg) outin(prompt, reply, sizeof(reply)); mp = findmethod(reply); if(mp){ - bargc = getfields(reply, bargv, Nbarg-1, 1, " "); + bargc = tokenize(reply, bargv, Nbarg-1); cp = strchr(reply, '!'); if(cp) strcpy(sys, cp+1); diff --git a/boot/bootcache.c b/boot/bootcache.c index ebe3a6c59d341425fadd8f333b0514fadfa1be6e..c8efd98f976a9d00e4f1888e7ce825657775a50a 100644 --- a/boot/bootcache.c +++ b/boot/bootcache.c @@ -17,7 +17,7 @@ cache(int fd) readfile("#e/cfs", buf, sizeof(buf)); if(*buf){ - argc = getfields(buf, argv, 4, 1, " "); + argc = tokenize(buf, argv, 4); for(i = 0; i < argc; i++){ if(strcmp(argv[i], "off") == 0) return fd; diff --git a/ip/arp.c b/ip/arp.c index 936594660cb7eae4debcc2e1492e5f5a2617d9e6..a69b4ab2fb5b9dcc1a95ec245342e90a0daccdd2 100644 --- a/ip/arp.c +++ b/ip/arp.c @@ -271,7 +271,7 @@ arpwrite(Fs *fs, char *s, int len) if(len > 0 && buf[len-1] == '\n') buf[len-1] = 0; - n = getfields(buf, f, 4, 1, " "); + n = tokenize(buf, f, 4); if(strcmp(f[0], "flush") == 0){ qlock(arp); for(a = arp->cache; a < &arp->cache[NCACHE]; a++){ diff --git a/ip/icmp.c b/ip/icmp.c index b1c90c49e5b3935c1107226d0a8abaaaade9f0d5..dd14ed6a64ffd0d27e2431d2641c25dce5d69695 100644 --- a/ip/icmp.c +++ b/ip/icmp.c @@ -28,6 +28,7 @@ typedef struct Icmp { enum { /* Packet Types */ EchoReply = 0, + UnreachableV6 = 1, Unreachable = 3, SrcQuench = 4, Redirect = 5, @@ -51,6 +52,7 @@ enum char *icmpnames[Maxtype+1] = { +[UnreachableV6] "UnreachableV6", [EchoReply] "EchoReply", [Unreachable] "Unreachable", [SrcQuench] "SrcQuench", @@ -293,7 +295,7 @@ static char *unreachcode[] = [1] "host unreachable", [2] "protocol unreachable", [3] "port unreachable", -[4] "fragmentation needed and DF set", +[4] "unfragmentable", [5] "source route failed", }; @@ -307,6 +309,9 @@ icmpiput(Proto *icmp, Ipifc*, Block *bp) char *msg; char m2[128]; Icmppriv *ipriv; + int code; + ushort x; + uchar dst[IPaddrlen]; ipriv = icmp->priv; @@ -344,10 +349,23 @@ icmpiput(Proto *icmp, Ipifc*, Block *bp) ipoput(icmp->f, r, 0, MAXTTL, DFLTTOS); break; case Unreachable: - if(p->code > 5 || p->code < 0) + code = p->code; + switch(code){ + default: msg = unreachcode[1]; - else + break; + case 5: + x = nhgets(p->seq); + msg = unreachcode[p->code]; + break; + case 0: + case 1: + case 2: + case 3: + case 4: msg = unreachcode[p->code]; + break; + } bp->rp += ICMP_IPSIZE+ICMP_HDRSIZE; if(blocklen(bp) < MinAdvise){ @@ -355,6 +373,10 @@ icmpiput(Proto *icmp, Ipifc*, Block *bp) goto raise; } p = (Icmp *)bp->rp; + if(code == 5){ + v4tov6(dst, p->dst); + update_mtucache(dst, x); + } pr = Fsrcvpcolx(icmp->f, p->proto); if(pr != nil && pr->advise != nil) { (*pr->advise)(pr, bp, msg); diff --git a/ip/ip.c b/ip/ip.c index 23f58d7ed79c07d722228a0de79ccb1136d7a7f1..a5219772ccd77154dd715310f9e2f4705d0b3ace 100644 --- a/ip/ip.c +++ b/ip/ip.c @@ -432,6 +432,20 @@ ipiput(Fs *f, Ipifc *ifc, Block *bp) freeblist(bp); return; } + + /* reassemble if the interface expects it */ + if(r->ifc->reassemble){ + frag = nhgets(h->frag); + if(frag) { + h->tos = 0; + if(frag & IP_MF) + h->tos = 1; + bp = ipreassemble(ip, frag, bp, h); + if(bp == nil) + return; + h = (Iphdr *)(bp->rp); + } + } ip->stats[ForwDatagrams]++; ipoput(f, bp, 1, h->ttl - 1, h->tos); @@ -439,8 +453,7 @@ ipiput(Fs *f, Ipifc *ifc, Block *bp) return; } - - + /* reassemble */ frag = nhgets(h->frag); if(frag) { h->tos = 0; @@ -716,3 +729,71 @@ ipcsum(uchar *addr) return (sum^0xffff); } + +enum +{ + Nmtucache= 128, +}; + +typedef struct MTUcache MTUcache; + +struct MTUcache +{ + uchar ip[IPaddrlen]; + ulong mtu; + ulong ms; +}; + +static struct { + Lock; + MTUcache c[Nmtucache]; +} mc; + +void +update_mtucache(uchar *ip, ulong mtu) +{ + MTUcache *oldest, *p; + + if(mtu < 512) + return; + + lock(&mc); + oldest = mc.c; + for(p = mc.c; p < &mc.c[Nmtucache]; p++){ + if(ipcmp(ip, p->ip) == 0){ + p->mtu = mtu; + p->ms = msec; + break; + } + if(p->ms < oldest->ms) + oldest = p; + } + if(p == &mc.c[Nmtucache]){ + ipmove(oldest->ip, ip); + oldest->mtu = mtu; + oldest->ms = msec; + } + unlock(&mc); +} + +ulong +restrict_mtu(uchar *ip, ulong mtu) +{ + MTUcache *p; + + lock(&mc); + for(p = mc.c; p < &mc.c[Nmtucache]; p++){ + if(p->ms + 1000*10*60 < msec){ + memset(p->ip, 0, sizeof(p->ip)); + p->ms = 0; + } + if(ipcmp(ip, p->ip) == 0){ + if(p->mtu < mtu) + mtu = p->mtu; + break; + } + } + unlock(&mc); + + return mtu; +} diff --git a/ip/ip.h b/ip/ip.h index d4197c55f5784e00e86f3377dda21c4f70527bce..5e192c4ec0751598199a01c94902e3bddedb0bc8 100644 --- a/ip/ip.h +++ b/ip/ip.h @@ -174,6 +174,7 @@ struct Ipifc int maxmtu; /* Maximum transfer unit */ int minmtu; /* Minumum tranfer unit */ void *arg; /* medium specific */ + int reassemble; /* reassemble IP packets before forwarding */ /* these are used so that we can unbind on the fly */ Lock idlock; @@ -543,6 +544,8 @@ extern int ipstats(Fs*, char*, int); extern ushort ptclbsum(uchar*, int); extern ushort ptclcsum(Block*, int, int); extern void ip_init(Fs*); +extern void update_mtucache(uchar*, ulong); +extern ulong restrict_mtu(uchar*, ulong); /* * bootp.c diff --git a/ip/ipifc.c b/ip/ipifc.c index 4d5e03f869b6615deb5d667e30f34f22f347a8cc..1761cf3e450c44c10782870fa9b4b1c7aba1a883 100644 --- a/ip/ipifc.c +++ b/ip/ipifc.c @@ -173,6 +173,7 @@ ipifcunbind(Ipifc *ifc) (*ifc->m->unbind)(ifc); memset(ifc->dev, 0, sizeof(ifc->dev)); ifc->arg = nil; + ifc->reassemble = 0; /* hangup queues to stop queuing of packets */ qhangup(ifc->conv->rq, "unbind"); @@ -288,6 +289,7 @@ ipifccreate(Conv *c) ifc->conv = c; ifc->unbinding = 0; ifc->m = nil; + ifc->reassemble = 0; } /* @@ -636,7 +638,10 @@ ipifcctl(Conv* c, char**argv, int argc) return ipifcleavemulti(ifc, argv, argc); else if(strcmp(argv[0], "mtu") == 0) return ipifcsetmtu(ifc, argv, argc); - else if(strcmp(argv[0], "iprouting") == 0){ + else if(strcmp(argv[0], "reassemble") == 0){ + ifc->reassemble = 1; + return nil; + } else if(strcmp(argv[0], "iprouting") == 0){ i = 1; if(argc > 1) i = atoi(argv[1]); diff --git a/ip/netlog.c b/ip/netlog.c index d7be9a8e32bb12f67df69497543bcf2c46ec2b0f..080e8557b28973991901a89df0659e8616da7901 100644 --- a/ip/netlog.c +++ b/ip/netlog.c @@ -167,7 +167,7 @@ netlogctl(Fs *f, char* s, int len) if(len > 0 && buf[len-1] == '\n') buf[len-1] = 0; - n = getfields(buf, fields, 10, 1, " "); + n = tokenize(buf, fields, 10); if(n < 2) return Ebadnetctl; diff --git a/ip/tcp.c b/ip/tcp.c index fcbf58ade2eaaae74d6128fac9c80e837e6650c4..e74541f07ba7cc9b3dfde64c0beeb8cea8bdd894 100644 --- a/ip/tcp.c +++ b/ip/tcp.c @@ -649,7 +649,7 @@ tcpmtu(Conv *s) mtu = ifc->maxmtu - ifc->m->hsize - (TCP_PKT + TCP_HDRSIZE); if(mtu < 4) mtu = DEF_MSS; - return mtu; + return restrict_mtu(s->raddr, mtu); } void @@ -2183,24 +2183,45 @@ tcpadvise(Proto *tcp, Block *bp, char *msg) /* Look for a connection */ qlock(tcp); - for(p = tcp->conv; *p; p++) { - s = *p; - tcb = (Tcpctl*)s->ptcl; - if(s->rport == pdest) - if(s->lport == psource) - if(tcb->state != Closed) - if(ipcmp(s->raddr, dest) == 0) - if(ipcmp(s->laddr, source) == 0){ - qlock(s); - qunlock(tcp); - switch(tcb->state){ - case Syn_sent: - localclose(s, msg); - break; + if(strcmp(msg, "unfragmentable") == 0){ + for(p = tcp->conv; *p; p++) { + s = *p; + tcb = (Tcpctl*)s->ptcl; + if(tcb->state != Closed) + if(ipcmp(s->raddr, dest) == 0) + if(ipcmp(s->laddr, source) == 0){ + qlock(s); + qunlock(tcp); + switch(tcb->state){ + case Syn_sent: + localclose(s, msg); + break; + } + qunlock(s); + freeblist(bp); + return; + } + } + } else { + for(p = tcp->conv; *p; p++) { + s = *p; + tcb = (Tcpctl*)s->ptcl; + if(s->rport == pdest) + if(s->lport == psource) + if(tcb->state != Closed) + if(ipcmp(s->raddr, dest) == 0) + if(ipcmp(s->laddr, source) == 0){ + qlock(s); + qunlock(tcp); + switch(tcb->state){ + case Syn_sent: + localclose(s, msg); + break; + } + qunlock(s); + freeblist(bp); + return; } - qunlock(s); - freeblist(bp); - return; } } qunlock(tcp); diff --git a/pc/devfloppy.c b/pc/devfloppy.c index 28e39edb6cc80e97d7321b3ee77776bdb70dc521..5c4bdf0b2bd9dc4c8867e295378507f9176a7dd5 100644 --- a/pc/devfloppy.c +++ b/pc/devfloppy.c @@ -904,7 +904,7 @@ floppyformat(FDrive *dp, char *params) /* * set the type */ - if(getfields(params, f, 3, 1, " ") > 1){ + if(tokenize(params, f, 3) > 1){ for(t = floppytype; t < &floppytype[nelem(floppytype)]; t++){ if(strcmp(f[1], t->name)==0 && t->dt==dp->dt){ dp->t = t; diff --git a/pc/devpccard.c b/pc/devpccard.c index ee79e2dd4a38fa0e66af22f061984828529bc588..163117778f09a03607797fdfdb80eec5c4f5266d 100644 --- a/pc/devpccard.c +++ b/pc/devpccard.c @@ -1326,7 +1326,7 @@ pccardwrite(Chan *c, void *v, long n, vlong) memmove(buf, v, n); buf[n] = '\0'; - nf = getfields(buf, field, Ncmd, 1, " \t\n"); + nf = tokenize(buf, field, Ncmd); for (i = 0; i != nf; i++) { if (!strcmp(field[i], "down")) { diff --git a/pc/devusb.c b/pc/devusb.c index 4979d8e64605d06fa725388b71223dd13ab258d0..22bb23cd231b27934f663c987e9c1822b9902648 100644 --- a/pc/devusb.c +++ b/pc/devusb.c @@ -2014,7 +2014,7 @@ usbwrite(Chan *c, void *a, long n, vlong offset) n = sizeof(cmd)-1; memmove(cmd, a, n); cmd[n] = 0; - nf = getfields(cmd, fields, nelem(fields), 0, " \t\n"); + nf = tokenize(cmd, fields, nelem(fields)); if(nf < 2) error(Ebadarg); id = strtol(fields[1], nil, 0); @@ -2038,7 +2038,7 @@ usbwrite(Chan *c, void *a, long n, vlong offset) n = sizeof(cmd)-1; memmove(cmd, a, n); cmd[n] = 0; - nf = getfields(cmd, fields, nelem(fields), 0, " \t\n"); + nf = tokenize(cmd, fields, nelem(fields)); if(nf > 1 && strcmp(fields[0], "speed") == 0){ d->ls = strtoul(fields[1], nil, 0) == 0; } else if(nf > 3 && strcmp(fields[0], "class") == 0){ diff --git a/pc/devvga.c b/pc/devvga.c index 5d8444e3e1792a61930bf613e03eff672a603ead..7e80f6d0422ccd5489f382e465c91a5fd95f8fd7 100644 --- a/pc/devvga.c +++ b/pc/devvga.c @@ -184,7 +184,7 @@ vgactl(char* a) extern VGAdev *vgadev[]; extern VGAcur *vgacur[]; - n = getfields(a, field, nelem(field), 1, " \t\n"); + n = tokenize(a, field, nelem(field)); if(n < 1) error(Ebadarg); diff --git a/pc/vgamach64xx.c b/pc/vgamach64xx.c index 7518ac79ec64560a7b982fa4e43e8ec2add04e09..ff1b385b97df1f1bbdaf8fba036d9a7a66513af7 100644 --- a/pc/vgamach64xx.c +++ b/pc/vgamach64xx.c @@ -1174,7 +1174,7 @@ mach64xxovlctl(VGAscr *scr, Chan *c, void *a, int) if (!mach64type->m64_vtgt) error(Enodev); - nfields = getfields(a, field, nelem(field), 1, "\t\n\r "); + nfields = tokenize(a, field, nelem(field)); if (nfields < 1) error(Ebadarg); diff --git a/port/devaudio.c b/port/devaudio.c index 76ac17ee7fe8d0bc3c3cae9f7c7dbd8a780e7bb3..e5ed7ebe8e1017074e6052741dbfd1e48f386d75 100644 --- a/port/devaudio.c +++ b/port/devaudio.c @@ -1090,7 +1090,7 @@ audiowrite(Chan *c, void *vp, long n, vlong) memmove(buf, a, n); buf[n] = '\0'; - nf = getfields(buf, field, Ncmd, 1, " \t\n"); + nf = tokenize(buf, field, Ncmd); for(i = 0; i < nf; i++){ /* * a number is volume diff --git a/port/devdraw.c b/port/devdraw.c index 0a5dbf8ee64b5df0699dd4c25ce3826054881a89..fa16e5826943df710b66948d6faf13fa48e99deb 100644 --- a/port/devdraw.c +++ b/port/devdraw.c @@ -1159,7 +1159,7 @@ drawwrite(Chan *c, void *a, long n, vlong) a = (char*)a + i; m -= i; *q = 0; - if(getfields(buf, fields, nelem(fields), 1, " ") != 4) + if(tokenize(buf, fields, nelem(fields)) != 4) error(Ebadarg); i = strtoul(fields[0], 0, 0); red = strtoul(fields[1], 0, 0); diff --git a/port/devmouse.c b/port/devmouse.c index 1f590c651d5d7294f423d887b8f2a5394431801c..0ce8186eefde113f8d7b0df59a1fb49808a72084 100644 --- a/port/devmouse.c +++ b/port/devmouse.c @@ -343,7 +343,7 @@ mousewrite(Chan *c, void *va, long n, vlong) buf[n-1] = 0; else buf[n] = 0; - nf = getfields(buf, field, 3, 1, " "); + nf = tokenize(buf, field, 3); if(strcmp(field[0], "swap") == 0){ if(mouseswap) setbuttonmap("123"); diff --git a/port/devproc.c b/port/devproc.c index b0b0927134c0a117b427a4067ab46d33b28af0c0..385b89dc0f3b065861cbe7897cf8b65defab6810 100644 --- a/port/devproc.c +++ b/port/devproc.c @@ -240,11 +240,14 @@ procopen(Chan *c, int omode) error(Eperm); break; + case Qmem: + if(p->privatemem) + error(Eperm); + /* fall through */ case Qargs: case Qctl: case Qnote: case Qnoteid: - case Qmem: case Qstatus: case Qwait: case Qregs: @@ -507,17 +510,14 @@ procread(Chan *c, void *va, long n, vlong off) || (offset >= USTKTOP-USTKSIZE && offset < USTKTOP)) return procctlmemio(p, offset, n, va, 1); - /* Protect crypt key memory */ - if(offset+n >= palloc.cmembase && offset < palloc.cmemtop) - error(Eperm); - - /* validate physical kernel addresses */ + /* validate kernel addresses */ if(offset < (ulong)end) { if(offset+n > (ulong)end) n = (ulong)end - offset; memmove(a, (char*)offset, n); return n; } + /* conf.base* and conf.npage* are set by xinit to refer to kernel allocation, not user pages */ if(offset >= conf.base0 && offset < conf.npage0){ if(offset+n > conf.npage0) n = conf.npage0 - offset; @@ -1070,6 +1070,9 @@ procctlreq(Proc *p, char *va, int n) error(Ebadctl); procctlclosefiles(p, 0, atoi(buf+6)); }else + if(strncmp(buf, "private", 7) == 0) + p->privatemem = 1; + else if(strncmp(buf, "pri", 3) == 0) { if(n < 4) error(Ebadctl); diff --git a/port/devsd.c b/port/devsd.c index 9b9f775e0c384932286e0be6908c54e619e444ff..10f53400d4447a4889124c32f90b1663295f4182 100644 --- a/port/devsd.c +++ b/port/devsd.c @@ -205,7 +205,7 @@ sdinitpart(SDunit* unit) for(p = getconf(buf); p != nil; p = q){ if(q = strchr(p, '/')) *q++ = '\0'; - nf = getfields(p, f, nelem(f), 1, " \t\r"); + nf = tokenize(p, f, nelem(f)); if(nf < 3) continue; @@ -1100,7 +1100,7 @@ sdwrite(Chan *c, void *a, long n, vlong off) cd.o_spec = '\0'; memset(&cd.o_cf, 0, sizeof(DevConf)); - nf = getfields(buf, field, Ncmd, 1, " \t\n"); + nf = tokenize(buf, field, Ncmd); for (i = 0; i < nf; i++) { char *opt = field[i++]; if (i >= nf) diff --git a/port/devuart.c b/port/devuart.c index cc14c8fdd9110998a58ca6292520b49f7985e39f..ff7a906474da72b6738d4c328d26c7fedbab0bdf 100644 --- a/port/devuart.c +++ b/port/devuart.c @@ -318,7 +318,7 @@ uartctl(Uart *p, char *cmd) char *f[16]; int i, n, nf; - nf = getfields(cmd, f, nelem(f), 1, " \t\n"); + nf = tokenize(cmd, f, nelem(f)); for(i = 0; i < nf; i++){ if(strncmp(f[i], "break", 5) == 0){ (*p->phys->dobreak)(p, 0); diff --git a/port/parse.c b/port/parse.c index eba5d94f16752c50e9a733290f42c1970711d3bb..333374170585b790b9caba0408573b9db52aaaf8 100644 --- a/port/parse.c +++ b/port/parse.c @@ -5,6 +5,31 @@ #include "fns.h" #include "../port/error.h" +/* + * Generous estimate of number of fields, including terminal nil pointer + */ +static int +ncmdfield(char *p, int n) +{ + int white, nwhite; + char *ep; + int nf; + + if(p == nil) + return 1; + + nf = 0; + ep = p+n; + white = 1; /* first text will start field */ + while(p < ep){ + nwhite = (strchr(" \t\r\n", *p++ & 0xFF) != 0); /* UTF is irrelevant */ + if(white && !nwhite) /* beginning of field */ + nf++; + white = nwhite; + } + return nf+1; /* +1 for nil */ +} + /* * parse a command written to a device */ @@ -15,13 +40,13 @@ parsecmd(char *p, int n) int nf; char *sp; - /* count fields and allocate a big enough cmdbuf */ - for(nf = 1, sp = p; sp != nil && *sp; nf++, sp = strchr(sp+1, ' ')) - ; - sp = smalloc(sizeof(*cb) + n + 1 + nf*sizeof(char*)); + nf = ncmdfield(p, n); + + /* allocate Cmdbuf plus string pointers plus copy of string including \0 */ + sp = smalloc(sizeof(*cb) + nf * sizeof(char*) + n + 1); cb = (Cmdbuf*)sp; - cb->buf = sp+sizeof(*cb); - cb->f = (char**)(cb->buf + n + 1); + cb->f = (char**)(&cb[1]); + cb->buf = (char*)(&cb->f[nf]); if(up!=nil && waserror()){ free(cb); @@ -36,7 +61,9 @@ parsecmd(char *p, int n) n--; cb->buf[n] = '\0'; - cb->nf = getfields(cb->buf, cb->f, nf, 1, " "); + cb->nf = tokenize(cb->buf, cb->f, nf-1); + cb->f[cb->nf] = nil; + return cb; } diff --git a/port/portdat.h b/port/portdat.h index 7ca9dc22c713d15ee829e1fe75d197ee9aa8b0df..86add7aca762e1376fd63675ece58a2beb29ff90 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -470,8 +470,6 @@ struct Palloc Lock hashlock; Rendez r; /* Sleep for free mem */ QLock pwait; /* Queue of procs waiting for memory */ - ulong cmembase; /* Key memory */ - ulong cmemtop; }; struct Waitq @@ -582,6 +580,7 @@ struct Proc QLock debug; /* to access debugging elements of User */ Proc *pdbg; /* the debugging process */ ulong procmode; /* proc device file mode */ + ulong privatemem; /* proc does not let anyone read mem */ int hang; /* hang at next exec for debug */ int procctl; /* Control for /proc debugging */ ulong pc; /* DEBUG only */ @@ -710,6 +709,11 @@ struct Logflag { int mask; }; +enum +{ + NCMDFIELD = 128 +}; + struct Cmdbuf { char *buf; diff --git a/port/proc.c b/port/proc.c index a38991be067e86dc7c90f92205c41ac298c23a88..c8c6bd24f4dc4fb9ad6eb30d054f5b71617a02df 100644 --- a/port/proc.c +++ b/port/proc.c @@ -338,6 +338,7 @@ newproc(void) p->movetime = 0; p->wired = 0; p->ureg = 0; + p->privatemem = 0; p->errstr = p->errbuf0; p->syserrstr = p->errbuf1; p->errbuf0[0] = '\0'; diff --git a/port/sysproc.c b/port/sysproc.c index ff1d28e876f817dfd13b0983094f69d0e62cf281..a6ddc67124a4d85df02df8e76c2d7270172b4ca9 100644 --- a/port/sysproc.c +++ b/port/sysproc.c @@ -471,6 +471,7 @@ sysexec(ulong *arg) up->nnote = 0; up->notify = 0; up->notified = 0; + up->privatemem = 0; procsetup(up); qunlock(&up->debug); if(up->hang)