--- /386/include/ape/math.h Thu Feb 28 23:09:16 2013 +++ /386/include/ape/math.h Mon Mar 4 22:29:50 2013 @@ -72,4 +72,7 @@ } #endif +#define isnan(x) isNaN(x) +#define isinf(x) isInf(x, 0) + #endif /* __MATH */ --- /arm/include/ape/math.h Fri Mar 5 15:01:27 2004 +++ /arm/include/ape/math.h Mon Mar 4 22:29:50 2013 @@ -15,6 +15,7 @@ extern double atan(double); extern double atan2(double, double); extern double cos(double); +extern double hypot(double, double); extern double sin(double); extern double tan(double); extern double cosh(double); @@ -72,6 +73,6 @@ #endif #define isnan(x) isNaN(x) -#define isinf(x) isInf(x) +#define isinf(x) isInf(x, 0) #endif /* __MATH */ --- /mips/include/ape/math.h Fri Mar 5 15:01:27 2004 +++ /mips/include/ape/math.h Mon Mar 4 22:29:51 2013 @@ -15,6 +15,7 @@ extern double atan(double); extern double atan2(double, double); extern double cos(double); +extern double hypot(double, double); extern double sin(double); extern double tan(double); extern double cosh(double); @@ -72,6 +73,6 @@ #endif #define isnan(x) isNaN(x) -#define isinf(x) isInf(x) +#define isinf(x) isInf(x, 0) #endif /* __MATH */ --- /power/include/ape/math.h Fri Mar 5 15:01:27 2004 +++ /power/include/ape/math.h Mon Mar 4 22:29:51 2013 @@ -15,6 +15,7 @@ extern double atan(double); extern double atan2(double, double); extern double cos(double); +extern double hypot(double, double); extern double sin(double); extern double tan(double); extern double cosh(double); @@ -72,6 +73,6 @@ #endif #define isnan(x) isNaN(x) -#define isinf(x) isInf(x) +#define isinf(x) isInf(x, 0) #endif /* __MATH */ --- /sparc/include/ape/math.h Fri Mar 5 15:01:28 2004 +++ /sparc/include/ape/math.h Mon Mar 4 22:29:51 2013 @@ -15,6 +15,7 @@ extern double atan(double); extern double atan2(double, double); extern double cos(double); +extern double hypot(double, double); extern double sin(double); extern double tan(double); extern double cosh(double); @@ -72,6 +73,6 @@ #endif #define isnan(x) isNaN(x) -#define isinf(x) isInf(x) +#define isinf(x) isInf(x, 0) #endif /* __MATH */ --- /sys/include/ape/limits.h Thu Feb 28 21:22:44 2002 +++ /sys/include/ape/limits.h Sat Mar 2 00:42:33 2013 @@ -49,6 +49,7 @@ #define _POSIX_TIMER_MAX 32 #define _POSIX_TZNAME_MAX 3 + /* pedagogy: those that standard allows omitting are commented out */ /*#define AIO_LIST_MAX _POSIX_AIO_LIST_MAX */ /*#define AIO_MAX _POSIX_AIO_MAX */ @@ -65,6 +66,7 @@ #define NGROUPS_MAX 10 /*#define OPEN_MAX _POSIX_OPEN_MAX */ /*#define PAGESIZE 1 */ +#define PASS_MAX 64 /*#define PATH_MAX _POSIX_PATH_MAX */ /*#define PIPE_BUF _POSIX_PIPE_BUF */ /*#define RTSIG_MAX _POSIX_RTSIG_MAX */ --- /sys/man/1/bind Mon Dec 3 00:42:11 2007 +++ /sys/man/1/bind Sat Mar 2 01:19:15 2013 @@ -198,7 +198,7 @@ To compile a program with the C library from July 16, 1992: .IP .EX -mount /srv/boot /n/dump dump +mount /srv/boot /n/dump main/archive bind /n/dump/1992/0716/mips/lib/libc.a /mips/lib/libc.a mk .EE --- /sys/src/9/pc/ether82563.c Thu Jan 24 23:09:52 2013 +++ /sys/src/9/pc/ether82563.c Tue Mar 5 22:49:27 2013 @@ -1258,7 +1258,6 @@ return; } - ctlr->edev = edev; /* point back to Ether* */ ctlr->nrd = Nrd; ctlr->ntd = Ntd; @@ -1294,6 +1293,7 @@ freeb(bp); } + ctlr->edev = edev; /* point back to Ether* */ ctlr->attached = 1; snprint(name, sizeof name, "#l%dl", edev->ctlrno); @@ -1356,7 +1356,8 @@ { Ctlr *ctlr; - for (ctlr = i82563ctlrhead; ctlr != nil; ctlr = ctlr->next) + for (ctlr = i82563ctlrhead; ctlr != nil && ctlr->edev != nil; + ctlr = ctlr->next) i82563interrupt(nil, ctlr->edev); } --- /sys/src/ape/lib/ap/plan9/_buf.c Sat Mar 10 06:13:27 2012 +++ /sys/src/ape/lib/ap/plan9/_buf.c Sat Mar 2 00:38:42 2013 @@ -289,15 +289,8 @@ if((rfds && FD_ISSET(i, rfds)) || (efds && FD_ISSET(i, efds))){ f = &_fdinfo[i]; if(!(f->flags&FD_BUFFERED)) - if(_startbuf(i) != 0) { + if(_startbuf(i) != 0) return -1; - } - b = f->buf; - if(rfds && FD_ISSET(i,rfds) && b->eof && b->n == 0) - if(efds == 0 || !FD_ISSET(i,efds)) { - errno = EBADF; /* how X tells a client is gone */ - return -1; - } } /* check wfds; for now, we'll say they are all ready */ --- /sys/src/ape/lib/v/plan9/getpass.c Wed Feb 6 20:48:12 2008 +++ /sys/src/ape/lib/v/plan9/getpass.c Sat Mar 2 00:43:13 2013 @@ -2,6 +2,7 @@ #define _RESEARCH_SOURCE #include #include +#include #include char * @@ -10,7 +11,7 @@ int c; char *p; FILE *fi; - static char pbuf[9]; + static char pbuf[PASS_MAX]; void (*sig)(int); if ((fi = fopen("/dev/cons", "r")) == NULL) @@ -28,7 +29,7 @@ else if (c == '\b') { if (p > pbuf) p--; - } else if (p < &pbuf[8]) + } else if (p < &pbuf[sizeof(pbuf)-1]) *p++ = c; *p = '\0'; --- /sys/src/cmd/5c/gc.h Wed Mar 28 20:37:38 2012 +++ /sys/src/cmd/5c/gc.h Mon Mar 4 22:15:20 2013 @@ -276,7 +276,6 @@ int mulcon(Node*, Node*); Multab* mulcon0(long); void nullwarn(Node*, Node*); -void sextern(Sym*, Node*, long, long); void gextern(Sym*, Node*, long, long); void outcode(void); void ieeedtod(Ieee*, double); --- /sys/src/cmd/5c/swt.c Wed Mar 28 20:37:38 2012 +++ /sys/src/cmd/5c/swt.c Mon Mar 4 22:15:20 2013 @@ -25,7 +25,7 @@ } if(nc < 5) { for(i=0; ival); gopcode(OEQ, nodconst(q->val), n, Z); patch(p, q->label); @@ -38,7 +38,7 @@ i = nc / 2; r = q+i; - if(debug['W']) + if(debug['K']) print("case > %.8llux\n", r->val); gopcode(OGT, nodconst(r->val), n, Z); sp = p; @@ -46,7 +46,7 @@ patch(p, r->label); swit2(q, i, def, n, tn); - if(debug['W']) + if(debug['K']) print("case < %.8llux\n", r->val); patch(sp, pc); swit2(r+1, nc-i-1, def, n, tn); @@ -59,7 +59,7 @@ gopcode(OCASE, nodconst((q+nc-1)->val - v), n, Z); patch(p, def); for(i=0; ival); while(q->val != v) { nextpc(); @@ -266,23 +266,6 @@ } p += 2; goto loop; -} - -void -sextern(Sym *s, Node *a, long o, long w) -{ - long e, lw; - - for(e=0; efrom.offset += o+e; - p->reg = lw; - p->to.type = D_SCONST; - memmove(p->to.sval, a->cstring+e, lw); - } } void --- /sys/src/cmd/6c/gc.h Wed Sep 2 14:10:13 2009 +++ /sys/src/cmd/6c/gc.h Mon Mar 4 22:15:20 2013 @@ -278,7 +278,6 @@ void bitstore(Node*, Node*, Node*, Node*, Node*); long outstring(char*, long); void nullwarn(Node*, Node*); -void sextern(Sym*, Node*, long, long); void gextern(Sym*, Node*, long, long); void outcode(void); void ieeedtod(Ieee*, double); --- /sys/src/cmd/6c/swt.c Wed Feb 20 03:38:53 2013 +++ /sys/src/cmd/6c/swt.c Mon Mar 4 22:15:20 2013 @@ -9,7 +9,7 @@ if(nc < 5) { for(i=0; ival); gcmp(OEQ, n, q->val); patch(p, q->label); @@ -21,7 +21,7 @@ } i = nc / 2; r = q+i; - if(debug['W']) + if(debug['K']) print("case > %.8llux\n", r->val); gcmp(OGT, n, r->val); sp = p; @@ -30,7 +30,7 @@ patch(p, r->label); swit1(q, i, def, n); - if(debug['W']) + if(debug['K']) print("case < %.8llux\n", r->val); patch(sp, pc); swit1(r+1, nc-i-1, def, n); @@ -125,23 +125,6 @@ n--; } return r; -} - -void -sextern(Sym *s, Node *a, long o, long w) -{ - long e, lw; - - for(e=0; efrom.offset += o+e; - p->from.scale = lw; - p->to.type = D_SCONST; - memmove(p->to.sval, a->cstring+e, lw); - } } void --- /sys/src/cmd/8c/gc.h Thu Mar 8 06:38:41 2012 +++ /sys/src/cmd/8c/gc.h Mon Mar 4 22:15:20 2013 @@ -275,7 +275,6 @@ void bitstore(Node*, Node*, Node*, Node*, Node*); long outstring(char*, long); void nullwarn(Node*, Node*); -void sextern(Sym*, Node*, long, long); void gextern(Sym*, Node*, long, long); void outcode(void); void ieeedtod(Ieee*, double); --- /sys/src/cmd/8c/swt.c Wed Feb 20 03:38:53 2013 +++ /sys/src/cmd/8c/swt.c Mon Mar 4 22:15:20 2013 @@ -9,7 +9,7 @@ if(nc < 5) { for(i=0; ival); gopcode(OEQ, n->type, n, nodconst(q->val)); patch(p, q->label); @@ -21,7 +21,7 @@ } i = nc / 2; r = q+i; - if(debug['W']) + if(debug['K']) print("case > %.8llux\n", r->val); gopcode(OGT, n->type, n, nodconst(r->val)); sp = p; @@ -30,7 +30,7 @@ patch(p, r->label); swit1(q, i, def, n); - if(debug['W']) + if(debug['K']) print("case < %.8llux\n", r->val); patch(sp, pc); swit1(r+1, nc-i-1, def, n); @@ -125,23 +125,6 @@ n--; } return r; -} - -void -sextern(Sym *s, Node *a, long o, long w) -{ - long e, lw; - - for(e=0; efrom.offset += o+e; - p->from.scale = lw; - p->to.type = D_SCONST; - memmove(p->to.sval, a->cstring+e, lw); - } } void --- /sys/src/cmd/aan.c Mon Apr 16 21:51:11 2012 +++ /sys/src/cmd/aan.c Tue Mar 5 22:45:29 2013 @@ -17,9 +17,10 @@ K = 1024, Bufsize = 8 * K, Stacksize = 8 * K, - Timer = 0, // Alt channels. + Timer = 0, /* Alt channels. */ Unsent = 1, - Maxto = 24 * 3600, // A full day to reconnect. + Maxto = 24 * 3600, /* A full day to reconnect. */ + Hdrsz = 12, }; typedef struct Endpoints Endpoints; @@ -31,62 +32,64 @@ }; typedef struct { - ulong nb; // Number of data bytes in this message - ulong msg; // Message number - ulong acked; // Number of messages acked + ulong nb; /* Number of data bytes in this message */ + ulong msg; /* Message number */ + ulong acked; /* Number of messages acked */ } Hdr; -typedef struct t_Buf { - Hdr hdr; - uchar buf[Bufsize]; +typedef struct { + Hdr hdr; + uchar buf[Bufsize]; } Buf; -static char *progname; -static Channel *unsent; -static Channel *unacked; -static Channel *empty; -static int netfd; -static int inmsg; +static char *Logname = LOGNAME; +static int client; +static int debug; static char *devdir; -static int debug; -static int done; static char *dialstring; -static int maxto = Maxto; -static char *Logname = LOGNAME; -static int client; +static int done; +static int inmsg; +static int maxto = Maxto; +static int netfd; + +static Channel *empty; +static Channel *unacked; +static Channel *unsent; static Alt a[] = { /* c v op */ - { nil, nil, CHANRCV }, // timer - { nil, nil, CHANRCV }, // unsent - { nil, nil, CHANEND }, + { nil, nil, CHANRCV }, /* timer */ + { nil, nil, CHANRCV }, /* unsent */ + { nil, nil, CHANEND }, }; -static void fromnet(void*); -static void fromclient(void*); -static void reconnect(void); -static void synchronize(void); -static int sendcommand(ulong, ulong); -static void showmsg(int, char *, Buf *); -static int writen(int, uchar *, int); -static int getport(char *); -static void dmessage(int, char *, ...); -static void timerproc(void *); +static void dmessage(int, char *, ...); +static void freeendpoints(Endpoints *); +static void fromclient(void*); +static void fromnet(void*); static Endpoints *getendpoints(char *); -static void freeendpoints(Endpoints *); +static int getport(char *); +static void packhdr(Hdr *, uchar *); +static void reconnect(void); +static int sendcommand(ulong, ulong); +static void showmsg(int, char *, Buf *); +static void synchronize(void); +static void timerproc(void *); +static void unpackhdr(Hdr *, uchar *); +static int writen(int, uchar *, int); static void usage(void) { - fprint(2, "Usage: %s [-cd] [-m maxto] dialstring|netdir\n", progname); + fprint(2, "Usage: %s [-cd] [-m maxto] dialstring|netdir\n", argv0); threadexitsall("usage"); } static int catch(void *, char *s) { - if (strcmp(s, "alarm") == 0) { - syslog(0, Logname, "Timed out while waiting for client on %s, exiting...", + if (strstr(s, "alarm") != nil) { + syslog(0, Logname, "Timed out waiting for client on %s, exiting...", devdir); threadexitsall(nil); } @@ -96,12 +99,14 @@ void threadmain(int argc, char **argv) { - int i, failed; - Buf *b; + int i, fd, failed, delta; + vlong synctime, now; + char *p; + uchar buf[Hdrsz]; + Buf *b, *eb; Channel *timer; - vlong synctime; + Hdr hdr; - progname = argv[0]; ARGBEGIN { case 'c': client++; @@ -110,7 +115,7 @@ debug++; break; case 'm': - maxto = (int)strtol(EARGF(usage()), (char **)nil, 0); + maxto = strtol(EARGF(usage()), (char **)nil, 0); break; default: usage(); @@ -120,17 +125,14 @@ usage(); if (!client) { - char *p; - devdir = argv[0]; if ((p = strstr(devdir, "/local")) != nil) *p = '\0'; - } - else + }else dialstring = argv[0]; if (debug > 0) { - int fd = open("#c/cons", OWRITE|OCEXEC); + fd = open("#c/cons", OWRITE|OCEXEC); dup(fd, 2); } @@ -139,28 +141,28 @@ atnotify(catch, 1); unsent = chancreate(sizeof(Buf *), Nbuf); - unacked = chancreate(sizeof(Buf *), Nbuf); - empty = chancreate(sizeof(Buf *), Nbuf); - timer = chancreate(sizeof(uchar *), 1); + unacked= chancreate(sizeof(Buf *), Nbuf); + empty = chancreate(sizeof(Buf *), Nbuf); + timer = chancreate(sizeof(uchar *), 1); for (i = 0; i != Nbuf; i++) { - Buf *b = malloc(sizeof(Buf)); - sendp(empty, b); + eb = malloc(sizeof(Buf)); + sendp(empty, eb); } netfd = -1; if (proccreate(fromnet, nil, Stacksize) < 0) - sysfatal("%s; Cannot start fromnet; %r", progname); + sysfatal("Cannot start fromnet; %r"); - reconnect(); // Set up the initial connection. + reconnect(); /* Set up the initial connection. */ synchronize(); if (proccreate(fromclient, nil, Stacksize) < 0) - sysfatal("%s; Cannot start fromclient; %r", progname); + sysfatal("cannot start fromclient; %r"); if (proccreate(timerproc, timer, Stacksize) < 0) - sysfatal("%s; Cannot start timerproc; %r", progname); + sysfatal("Cannot start timerproc; %r"); a[Timer].c = timer; a[Unsent].c = unsent; @@ -169,17 +171,14 @@ synctime = nsec() + Synctime; failed = 0; while (!done) { - vlong now; - int delta; - if (failed) { - // Wait for the netreader to die. + /* Wait for the netreader to die. */ while (netfd >= 0) { dmessage(1, "main; waiting for netreader to die\n"); sleep(1000); } - // the reader died; reestablish the world. + /* the reader died; reestablish the world. */ reconnect(); synchronize(); failed = 0; @@ -189,13 +188,11 @@ delta = (synctime - nsec()) / MS(1); if (delta <= 0) { - Hdr hdr; - hdr.nb = 0; hdr.acked = inmsg; hdr.msg = -1; - - if (writen(netfd, (uchar *)&hdr, sizeof(Hdr)) < 0) { + packhdr(&hdr, buf); + if (writen(netfd, buf, sizeof(buf)) < 0) { dmessage(2, "main; writen failed; %r\n"); failed = 1; continue; @@ -207,18 +204,13 @@ switch (alt(a)) { case Timer: break; - case Unsent: sendp(unacked, b); b->hdr.acked = inmsg; - - if (writen(netfd, (uchar *)&b->hdr, sizeof(Hdr)) < 0) { - dmessage(2, "main; writen failed; %r\n"); - failed = 1; - } - - if (writen(netfd, b->buf, b->hdr.nb) < 0) { + packhdr(&b->hdr, buf); + if (writen(netfd, buf, sizeof(buf)) < 0 || + writen(netfd, b->buf, b->hdr.nb) < 0) { dmessage(2, "main; writen failed; %r\n"); failed = 1; } @@ -232,15 +224,13 @@ threadexitsall(nil); } - static void fromclient(void*) { + Buf *b; static int outmsg; - for (;;) { - Buf *b; - + do { b = recvp(empty); if ((int)(b->hdr.nb = read(0, b->buf, Bufsize)) <= 0) { if ((int)b->hdr.nb < 0) @@ -253,32 +243,29 @@ showmsg(1, "fromclient", b); sendp(unsent, b); - - if (b->hdr.nb == 0) - break; - } + } while (b->hdr.nb != 0); } static void fromnet(void*) { + int len, acked, i; + uchar buf[Hdrsz]; + Buf *b, *rb; static int lastacked; - Buf *b; b = (Buf *)malloc(sizeof(Buf)); assert(b); while (!done) { - int len, acked, i; - while (netfd < 0) { dmessage(1, "fromnet; waiting for connection... (inmsg %d)\n", inmsg); sleep(1000); } - // Read the header. - if ((len = readn(netfd, &b->hdr, sizeof(Hdr))) <= 0) { + /* Read the header. */ + if ((len = readn(netfd, buf, sizeof(buf))) <= 0) { if (len < 0) dmessage(1, "fromnet; (hdr) network failure; %r\n"); else @@ -287,8 +274,9 @@ netfd = -1; continue; } - dmessage(2, "fromnet: Got message, size %d, nb %d, msg %d\n", len, - b->hdr.nb, b->hdr.msg); + unpackhdr(&b->hdr, buf); + dmessage(2, "fromnet: Got message, size %d, nb %d, msg %d\n", + len, b->hdr.nb, b->hdr.msg); if (b->hdr.nb == 0) { if ((long)b->hdr.msg >= 0) { @@ -297,8 +285,9 @@ } continue; } - - if ((len = readn(netfd, b->buf, b->hdr.nb)) <= 0 || len != b->hdr.nb) { + + if ((len = readn(netfd, b->buf, b->hdr.nb)) <= 0 || + len != b->hdr.nb) { if (len == 0) dmessage(1, "fromnet; network closed\n"); else @@ -310,30 +299,25 @@ if (b->hdr.msg < inmsg) { dmessage(1, "fromnet; skipping message %d, currently at %d\n", - b->hdr.msg, inmsg); + b->hdr.msg, inmsg); continue; } - // Process the acked list. + /* Process the acked list. */ acked = b->hdr.acked - lastacked; for (i = 0; i != acked; i++) { - Buf *rb; - rb = recvp(unacked); if (rb->hdr.msg != lastacked + i) { dmessage(1, "rb %p, msg %d, lastacked %d, i %d\n", - rb, rb? rb->hdr.msg: -2, lastacked, i); + rb, rb? rb->hdr.msg: -2, lastacked, i); assert(0); } rb->hdr.msg = -1; sendp(empty, rb); - } + } lastacked = b->hdr.acked; - inmsg++; - showmsg(1, "fromnet", b); - if (writen(1, b->buf, len) < 0) sysfatal("fromnet; cannot write to client; %r"); } @@ -343,14 +327,13 @@ static void reconnect(void) { - char ldir[40]; + char err[32], ldir[40]; int lcfd, fd; + Endpoints *ep; if (dialstring) { syslog(0, Logname, "dialing %s", dialstring); while ((fd = dial(dialstring, nil, nil, nil)) < 0) { - char err[32]; - err[0] = '\0'; errstr(err, sizeof err); if (strstr(err, "connection refused")) { @@ -361,10 +344,7 @@ sleep(1000); } syslog(0, Logname, "reconnected to %s", dialstring); - } - else { - Endpoints *ep; - + } else { syslog(0, Logname, "waiting for connection on %s", devdir); alarm(maxto * 1000); if ((lcfd = listen(devdir, ldir)) < 0) @@ -380,8 +360,7 @@ syslog(0, Logname, "connected from %s", ep->rsys); freeendpoints(ep); } - - netfd = fd; // Wakes up the netreader. + netfd = fd; /* Wakes up the netreader. */ } static void @@ -389,14 +368,18 @@ { Channel *tmp; Buf *b; + uchar buf[Hdrsz]; - // Ignore network errors here. If we fail during - // synchronization, the next alarm will pick up - // the error. - + /* + * Ignore network errors here. If we fail during + * synchronization, the next alarm will pick up + * the error. + */ tmp = chancreate(sizeof(Buf *), Nbuf); while ((b = nbrecvp(unacked)) != nil) { - writen(netfd, (uchar *)b, sizeof(Hdr) + b->hdr.nb); + packhdr(&b->hdr, buf); + writen(netfd, buf, sizeof(buf)); + writen(netfd, b->buf, b->hdr.nb); sendp(tmp, b); } chanfree(unacked); @@ -410,32 +393,26 @@ dmessage(level, "%s; b == nil\n", s); return; } - - dmessage(level, - "%s; (len %d) %X %X %X %X %X %X %X %X %X (%p)\n", s, - b->hdr.nb, - b->buf[0], b->buf[1], b->buf[2], - b->buf[3], b->buf[4], b->buf[5], - b->buf[6], b->buf[7], b->buf[8], b); + dmessage(level, "%s; (len %d) %X %X %X %X %X %X %X %X %X (%p)\n", s, + b->hdr.nb, + b->buf[0], b->buf[1], b->buf[2], + b->buf[3], b->buf[4], b->buf[5], + b->buf[6], b->buf[7], b->buf[8], b); } static int writen(int fd, uchar *buf, int nb) { - int len = nb; + int n, len = nb; while (nb > 0) { - int n; - if (fd < 0) return -1; - if ((n = write(fd, buf, nb)) < 0) { dmessage(1, "writen; Write failed; %r\n"); return -1; } dmessage(2, "writen: wrote %d bytes\n", n); - buf += n; nb -= n; } @@ -446,6 +423,7 @@ timerproc(void *x) { Channel *timer = x; + while (!done) { sleep((Synctime / MS(1)) >> 1); sendp(timer, "timer"); @@ -459,7 +437,6 @@ if (level > debug) return; - va_start(arg, fmt); vfprint(2, fmt, arg); va_end(arg); @@ -473,7 +450,6 @@ char *sys, *serv; sys = serv = 0; - snprint(buf, sizeof buf, "%s/%s", dir, file); fd = open(buf, OREAD); if(fd >= 0){ @@ -518,3 +494,33 @@ free(ep); } +/* p must be a uchar* */ +#define U32GET(p) (p[0] | p[1]<<8 | p[2]<<16 | p[3]<<24) +#define U32PUT(p,v) (p)[0] = (v); (p)[1] = (v)>>8; \ + (p)[2] = (v)>>16; (p)[3] = (v)>>24 + +static void +packhdr(Hdr *hdr, uchar *buf) +{ + uchar *p; + + p = buf; + U32PUT(p, hdr->nb); + p += 4; + U32PUT(p, hdr->msg); + p += 4; + U32PUT(p, hdr->acked); +} + +static void +unpackhdr(Hdr *hdr, uchar *buf) +{ + uchar *p; + + p = buf; + hdr->nb = U32GET(p); + p += 4; + hdr->msg = U32GET(p); + p += 4; + hdr->acked = U32GET(p); +} --- /sys/src/cmd/cc/cc.h Sat Mar 10 00:07:03 2012 +++ /sys/src/cmd/cc/cc.h Mon Mar 4 22:15:21 2013 @@ -741,7 +741,6 @@ void ginit(void); long outstring(char*, long); long outlstring(ushort*, long); -void sextern(Sym*, Node*, long, long); void xcom(Node*); long exreg(Type*); long align(long, Type*, int); --- /sys/src/cmd/cc/sub.c Thu Mar 8 06:35:49 2012 +++ /sys/src/cmd/cc/sub.c Mon Mar 4 22:27:25 2013 @@ -1187,12 +1187,15 @@ char buf[STRINGSZ]; va_list arg; - if(debug['w']) { - Bprint(&diagbuf, "warning: "); + if(debug['w'] || debug['W']) { va_start(arg, fmt); vseprint(buf, buf+sizeof(buf), fmt, arg); va_end(arg); - Bprint(&diagbuf, "%L %s\n", (n==Z)? nearln: n->lineno, buf); + if(debug['W']) { + diag(n, "%s", buf); + return; + } + Bprint(&diagbuf, "warning: %L %s\n", (n==Z)? nearln: n->lineno, buf); if(n != Z) if(debug['v']) --- /sys/src/cmd/kc/gc.h Fri Mar 9 04:56:22 2012 +++ /sys/src/cmd/kc/gc.h Mon Mar 4 22:15:20 2013 @@ -267,7 +267,6 @@ Multab* mulcon0(Node*, long); int mulcon1(Node*, long, Node*); void nullwarn(Node*, Node*); -void sextern(Sym*, Node*, long, long); void gextern(Sym*, Node*, long, long); void outcode(void); void ieeedtod(Ieee*, double); --- /sys/src/cmd/kc/swt.c Wed Feb 20 03:38:53 2013 +++ /sys/src/cmd/kc/swt.c Mon Mar 4 22:15:20 2013 @@ -236,23 +236,6 @@ } void -sextern(Sym *s, Node *a, long o, long w) -{ - long e, lw; - - for(e=0; efrom.offset += o+e; - p->reg = lw; - p->to.type = D_SCONST; - memmove(p->to.sval, a->cstring+e, lw); - } -} - -void gextern(Sym *s, Node *a, long o, long w) { if(a->op == OCONST && typev[a->type->etype]) { --- /sys/src/cmd/ld/elf.c Thu Jan 1 01:00:00 1970 +++ /sys/src/cmd/ld/elf.c Tue Mar 5 22:52:01 2013 @@ -0,0 +1,266 @@ +/* + * emit 32- or 64-bit elf headers for any architecture. + * this is a component of ?l. + */ +#include "l.h" + +enum { + /* offsets into string table */ + Stitext = 1, + Stidata = 7, + Stistrtab = 13, +}; + +void +elfident(int bo, int class) +{ + strnput("\177ELF", 4); /* e_ident */ + cput(class); + cput(bo); /* byte order */ + cput(1); /* version = CURRENT */ + if(debug['P']){ /* boot/embedded/standalone */ + cput(255); + cput(0); + } + else{ + cput(0); /* osabi = SYSV */ + cput(0); /* abiversion = 3 */ + } + strnput("", 7); +} + +void +elfstrtab(void) +{ + /* string table */ + cput(0); + strnput(".text", 5); /* +1 */ + cput(0); + strnput(".data", 5); /* +7 */ + cput(0); + strnput(".strtab", 7); /* +13 */ + cput(0); + cput(0); +} + +void +elf32phdr(void (*putl)(long), ulong type, ulong off, ulong vaddr, ulong paddr, + ulong filesz, ulong memsz, ulong prots, ulong align) +{ + putl(type); + putl(off); + putl(vaddr); + putl(paddr); + putl(filesz); + putl(memsz); + putl(prots); + putl(align); +} + +void +elf32shdr(void (*putl)(long), ulong name, ulong type, ulong flags, ulong vaddr, + ulong off, ulong sectsz, ulong link, ulong addnl, ulong align, + ulong entsz) +{ + putl(name); + putl(type); + putl(flags); + putl(vaddr); + putl(off); + putl(sectsz); + putl(link); + putl(addnl); + putl(align); + putl(entsz); +} + +static void +elf32sectab(void (*putl)(long)) +{ + seek(cout, HEADR+textsize+datsize+symsize, 0); + elf32shdr(putl, Stitext, Progbits, Salloc|Sexec, INITTEXT, + HEADR, textsize, 0, 0, 0x10000, 0); + elf32shdr(putl, Stidata, Progbits, Salloc|Swrite, INITDAT, + HEADR+textsize, datsize, 0, 0, 0x10000, 0); + elf32shdr(putl, Stistrtab, Strtab, 1 << 5, 0, + HEADR+textsize+datsize+symsize+3*Shdr32sz, 14, 0, 0, 1, 0); + elfstrtab(); +} + +/* if addpsects > 0, putpsects must emit exactly that many psects. */ +void +elf32(int mach, int bo, int addpsects, void (*putpsects)(Putl)) +{ + ulong phydata; + void (*putw)(long), (*putl)(long); + + if(bo == ELFDATA2MSB){ + putw = wput; + putl = lput; + }else if(bo == ELFDATA2LSB){ + putw = wputl; + putl = lputl; + }else{ + print("elf32 byte order is mixed-endian\n"); + errorexit(); + return; + } + + elfident(bo, ELFCLASS32); + putw(EXEC); + putw(mach); + putl(1L); /* version = CURRENT */ + putl(entryvalue()); /* entry vaddr */ + putl(Ehdr32sz); /* offset to first phdr */ + if(debug['S']) + putl(HEADR+textsize+datsize+symsize); /* offset to first shdr */ + else + putl(0); + putl(0L); /* flags */ + putw(Ehdr32sz); + putw(Phdr32sz); + putw(3 + addpsects); /* # of Phdrs */ + putw(Shdr32sz); + if(debug['S']){ + putw(3); /* # of Shdrs */ + putw(2); /* Shdr table index */ + }else{ + putw(0); + putw(0); + } + + /* + * could include ELF headers in text -- 8l doesn't, + * but in theory it aids demand loading. + */ + elf32phdr(putl, PT_LOAD, HEADR, INITTEXT, INITTEXTP, + textsize, textsize, R|X, INITRND); /* text */ + /* + * we need INITDATP, but it has to be computed. + * assume distance between INITTEXT & INITTEXTP is also + * correct for INITDAT and INITDATP. + */ + phydata = INITDAT - (INITTEXT - INITTEXTP); + elf32phdr(putl, PT_LOAD, HEADR+textsize, INITDAT, phydata, + datsize, datsize+bsssize, R|W|X, INITRND); /* data */ + elf32phdr(putl, NOPTYPE, HEADR+textsize+datsize, 0, 0, + symsize, lcsize, R, 4); /* symbol table */ + if (addpsects > 0) + putpsects(putl); + cflush(); + + if(debug['S']) + elf32sectab(putl); +} + +/* + * elf64 + */ + +void +elf64phdr(void (*putl)(long), void (*putll)(vlong), ulong type, uvlong off, + uvlong vaddr, uvlong paddr, uvlong filesz, uvlong memsz, ulong prots, + uvlong align) +{ + putl(type); + putl(prots); + putll(off); + putll(vaddr); + putll(paddr); + putll(filesz); + putll(memsz); + putll(align); +} + +void +elf64shdr(void (*putl)(long), void (*putll)(vlong), ulong name, ulong type, + uvlong flags, uvlong vaddr, uvlong off, uvlong sectsz, ulong link, + ulong addnl, uvlong align, uvlong entsz) +{ + putl(name); + putl(type); + putll(flags); + putll(vaddr); + putll(off); + putll(sectsz); + putl(link); + putl(addnl); + putll(align); + putll(entsz); +} + +static void +elf64sectab(void (*putl)(long), void (*putll)(vlong)) +{ + seek(cout, HEADR+textsize+datsize+symsize, 0); + elf64shdr(putl, putll, Stitext, Progbits, Salloc|Sexec, INITTEXT, + HEADR, textsize, 0, 0, 0x10000, 0); + elf64shdr(putl, putll, Stidata, Progbits, Salloc|Swrite, INITDAT, + HEADR+textsize, datsize, 0, 0, 0x10000, 0); + elf64shdr(putl, putll, Stistrtab, Strtab, 1 << 5, 0, + HEADR+textsize+datsize+symsize+3*Shdr64sz, 14, 0, 0, 1, 0); + elfstrtab(); +} + +/* if addpsects > 0, putpsects must emit exactly that many psects. */ +void +elf64(int mach, int bo, int addpsects, void (*putpsects)(Putl)) +{ + uvlong phydata; + void (*putw)(long), (*putl)(long); + void (*putll)(vlong); + + if(bo == ELFDATA2MSB){ + putw = wput; + putl = lput; + putll = llput; + }else if(bo == ELFDATA2LSB){ + putw = wputl; + putl = lputl; + putll = llputl; + }else{ + print("elf64 byte order is mixed-endian\n"); + errorexit(); + return; + } + + elfident(bo, ELFCLASS64); + putw(EXEC); + putw(mach); + putl(1L); /* version = CURRENT */ + putll(entryvalue()); /* entry vaddr */ + putll(Ehdr64sz); /* offset to first phdr */ + if(debug['S']) + putll(HEADR+textsize+datsize+symsize); /* offset to 1st shdr */ + else + putll(0); + putl(0L); /* flags */ + putw(Ehdr64sz); + putw(Phdr64sz); + putw(3 + addpsects); /* # of Phdrs */ + putw(Shdr64sz); + if(debug['S']){ + putw(3); /* # of Shdrs */ + putw(2); /* Shdr table index */ + }else{ + putw(0); + putw(0); + } + + elf64phdr(putl, putll, PT_LOAD, HEADR, INITTEXT, INITTEXTP, + textsize, textsize, R|X, INITRND); /* text */ + /* + * see 32-bit ELF case for physical data address computation. + */ + phydata = INITDAT - (INITTEXT - INITTEXTP); + elf64phdr(putl, putll, PT_LOAD, HEADR+textsize, INITDAT, phydata, + datsize, datsize+bsssize, R|W, INITRND); /* data */ + elf64phdr(putl, putll, NOPTYPE, HEADR+textsize+datsize, 0, 0, + symsize, lcsize, R, 4); /* symbol table */ + if (addpsects > 0) + putpsects(putl); + cflush(); + + if(debug['S']) + elf64sectab(putl, putll); +} --- /sys/src/cmd/ld/elf.h Thu Jan 1 01:00:00 1970 +++ /sys/src/cmd/ld/elf.h Tue Mar 5 22:50:31 2013 @@ -0,0 +1,96 @@ +enum { + Ehdr32sz = 52, + Phdr32sz = 32, + Shdr32sz = 40, + + Ehdr64sz = 64, + Phdr64sz = 56, + Shdr64sz = 64, +}; + +/* from /sys/src/libmach/elf.h */ +enum { + /* Ehdr codes */ + MAG0 = 0, /* ident[] indexes */ + MAG1 = 1, + MAG2 = 2, + MAG3 = 3, + CLASS = 4, + DATA = 5, + VERSION = 6, + + ELFCLASSNONE = 0, /* ident[CLASS] */ + ELFCLASS32 = 1, + ELFCLASS64 = 2, + ELFCLASSNUM = 3, + + ELFDATANONE = 0, /* ident[DATA] */ + ELFDATA2LSB = 1, + ELFDATA2MSB = 2, + ELFDATANUM = 3, + + NOETYPE = 0, /* type */ + REL = 1, + EXEC = 2, + DYN = 3, + CORE = 4, + + NONE = 0, /* machine */ + M32 = 1, /* AT&T WE 32100 */ + SPARC = 2, /* Sun SPARC */ + I386 = 3, /* Intel 80386 */ + M68K = 4, /* Motorola 68000 */ + M88K = 5, /* Motorola 88000 */ + I486 = 6, /* Intel 80486 */ + I860 = 7, /* Intel i860 */ + MIPS = 8, /* Mips R2000 */ + S370 = 9, /* Amdhal */ + SPARC64 = 18, /* Sun SPARC v9 */ + POWER = 20, /* PowerPC */ + POWER64 = 21, /* PowerPC64 */ + ARM = 40, /* ARM */ + AMD64 = 62, /* Amd64 */ + ARM64 = 183, /* ARM64 */ + + NO_VERSION = 0, /* version, ident[VERSION] */ + CURRENT = 1, + + /* Phdr Codes */ + NOPTYPE = 0, /* type */ + PT_LOAD = 1, + DYNAMIC = 2, + INTERP = 3, + NOTE = 4, + SHLIB = 5, + PHDR = 6, + + R = 0x4, /* flags */ + W = 0x2, + X = 0x1, + + /* Shdr Codes */ + Progbits = 1, /* section types */ + Strtab = 3, + Nobits = 8, + + Swrite = 1, /* section attributes (flags) */ + Salloc = 2, + Sexec = 4, +}; + +typedef void (*Putl)(long); + +void elf32(int mach, int bo, int addpsects, void (*putpsects)(Putl)); +void elf32phdr(void (*putl)(long), ulong type, ulong off, ulong vaddr, + ulong paddr, ulong filesz, ulong memsz, ulong prots, ulong align); +void elf32shdr(void (*putl)(long), ulong name, ulong type, ulong flags, + ulong vaddr, ulong off, ulong sectsz, ulong link, ulong addnl, + ulong align, ulong entsz); + +void elf64(int mach, int bo, int addpsects, void (*putpsects)(Putl)); +void elf64phdr(void (*putl)(long), void (*putll)(vlong), ulong type, + uvlong off, uvlong vaddr, uvlong paddr, uvlong filesz, uvlong memsz, + ulong prots, uvlong align); +void elf64shdr(void (*putl)(long), void (*putll)(vlong), ulong name, + ulong type, uvlong flags, uvlong vaddr, uvlong off, uvlong sectsz, + ulong link, ulong addnl, uvlong align, uvlong entsz); --- /sys/src/cmd/ld/mkfile Thu Jan 1 01:00:00 1970 +++ /sys/src/cmd/ld/mkfile Tue Mar 5 22:50:32 2013 @@ -0,0 +1,2 @@ +all clean nuke install installall safeinstall safeinstallall:V: + date --- /sys/src/cmd/qc/gc.h Thu Mar 8 06:42:57 2012 +++ /sys/src/cmd/qc/gc.h Mon Mar 4 22:15:21 2013 @@ -283,7 +283,6 @@ Multab* mulcon0(Node*, long); int mulcon1(Node*, long, Node*); void nullwarn(Node*, Node*); -void sextern(Sym*, Node*, long, long); void gextern(Sym*, Node*, long, long); void outcode(void); void ieeedtod(Ieee*, double); --- /sys/src/cmd/qc/swt.c Wed Feb 20 03:38:53 2013 +++ /sys/src/cmd/qc/swt.c Mon Mar 4 22:15:20 2013 @@ -240,23 +240,6 @@ } void -sextern(Sym *s, Node *a, long o, long w) -{ - long e, lw; - - for(e=0; efrom.offset += o+e; - p->reg = lw; - p->to.type = D_SCONST; - memmove(p->to.sval, a->cstring+e, lw); - } -} - -void gextern(Sym *s, Node *a, long o, long w) { if(a->op == OCONST && typev[a->type->etype]) { --- /sys/src/cmd/rc/havefork.c Tue May 12 19:36:33 2009 +++ /sys/src/cmd/rc/havefork.c Fri Mar 1 23:25:27 2013 @@ -71,8 +71,6 @@ } } -enum { Wordmax = 8192, }; - /* * Who should wait for the exit from the fork? */ @@ -81,8 +79,8 @@ { int c, pid; int pfd[2]; - char wd[Wordmax + 1]; - char *s, *ewd = &wd[Wordmax], *stop; + char wd[NTOK + 1]; + char *s, *ewd = &wd[NTOK], *stop; struct io *f; var *ifs = vlook("ifs"); word *v, *nextv; --- /sys/src/cmd/rc/plan9.c Mon Jul 19 22:44:48 2010 +++ /sys/src/cmd/rc/plan9.c Fri Mar 1 20:53:47 2013 @@ -29,12 +29,14 @@ "term", 0 }; -char Rcmain[]="/rc/lib/rcmain"; -char Fdprefix[]="/fd/"; +char *Rcmain = "/rc/lib/rcmain"; +char *Fdprefix = "/fd/"; + void execfinit(void); void execbind(void); void execmount(void); void execnewpgrp(void); + builtin Builtin[] = { "cd", execcd, "whatis", execwhatis, --- /sys/src/cmd/rc/rc.h Fri Mar 1 00:35:01 2013 +++ /sys/src/cmd/rc/rc.h Fri Mar 1 23:54:51 2013 @@ -1,38 +1,22 @@ /* - * Plan9 is defined for plan 9 - * Unix is defined for Unix + * Assume plan 9 by default; if Unix is defined, assume unix. * Please don't litter the code with ifdefs. The six below should be enough. */ -#define Plan9 -#ifdef Plan9 + +#ifndef Unix +/* plan 9 */ #include #include + #define NSIG 32 #define SIGINT 2 #define SIGQUIT 3 -#endif -#ifdef Unix -#define _BSD_EXTENSION -#define _PLAN9_SOURCE -#define _POSIX_SOURCE -#define _RESEARCH_SOURCE -#define _SUSV2_SOURCE - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef NSIG -#define NSIG 32 -#endif - -#define uintptr uintptr_t +#define fcntl(fd, op, arg) /* unix compatibility */ +#define F_SETFD +#define FD_CLOEXEC +#else +#include "unix.h" #endif #ifndef ERRMAX @@ -40,9 +24,12 @@ #endif #define YYMAXDEPTH 500 +#ifndef YYPREFIX #ifndef PAREN #include "x.tab.h" #endif +#endif + typedef struct tree tree; typedef struct word word; typedef struct io io; @@ -53,14 +40,14 @@ typedef struct thread thread; typedef struct builtin builtin; -#ifdef Plan9 +#ifndef Unix #pragma incomplete word #pragma incomplete io #endif struct tree{ int type; - int rtype, fd0, fd1; /* details of REDIR PIPE DUP tokens */ + int rtype, fd0, fd1; /* details of REDIR PIPE DUP tokens */ char *str; int quoted; int iskw; @@ -90,7 +77,7 @@ char *promptstr; int doprompt; -#define NTOK 8192 +#define NTOK 8192 /* maximum bytes in a word (token) */ char tok[NTOK]; @@ -123,7 +110,7 @@ void *Malloc(ulong); void efree(void *); -#define NOFILE 128 /* should come from */ +#define NOFILE 128 /* should come from on unix */ struct here{ tree *tag; @@ -161,7 +148,8 @@ */ #define PRD 0 #define PWR 1 -char Rcmain[], Fdprefix[]; + +char *Rcmain, *Fdprefix; /* * How many dot commands have we executed? * Used to ensure that -v flag doesn't print rcmain. --- /sys/src/cmd/rc/rcmain.unix Thu Jan 1 01:00:00 1970 +++ /sys/src/cmd/rc/rcmain.unix Fri Mar 1 23:35:27 2013 @@ -0,0 +1,34 @@ +# rcmain: unix version +if(~ $#home 0) home=$HOME +if(~ $#ifs 0) ifs=' +' +switch($#prompt){ +case 0 + prompt=('% ' ' ') +case 1 + prompt=($prompt ' ') +} +if(~ $rcname ?.out) prompt=('broken! ' ' ') +if(flag p) path=/bin +if not { + finit + if(~ $#path 0) path=(. /bin /usr/bin /usr/local/bin) +} +fn sigexit +if(! ~ $#cflag 0){ + if(flag l && test -r $home/lib/profile) . $home/lib/profile + status='' + eval $cflag +} +if not if(flag i){ + if(flag l && test -r $home/lib/profile) . $home/lib/profile + status='' + if(! ~ $#* 0) . $* + . -i /dev/fd/0 +} +if not if(~ $#* 0) . /dev/fd/0 +if not{ + status='' + . $* +} +exit $status --- /sys/src/cmd/rc/run.unix Thu Jan 1 01:00:00 1970 +++ /sys/src/cmd/rc/run.unix Fri Mar 1 23:52:54 2013 @@ -0,0 +1,20 @@ +yacc -d syn.y +cmp -s x.tab.h y.tab.h || cp y.tab.h x.tab.h +cc -DUnix -c -I. code.c +cc -DUnix -c -I. exec.c +cc -DUnix -c -I. getflags.c +cc -DUnix -c -I. glob.c +cc -DUnix -c -I. here.c +cc -DUnix -c -I. io.c +cc -DUnix -c -I. lex.c +cc -DUnix -c -I. pcmd.c +cc -DUnix -c -I. pfnc.c +cc -DUnix -c -I. simple.c +cc -DUnix -c -I. subr.c +cc -DUnix -c -I. trap.c +cc -DUnix -c -I. tree.c +cc -DUnix -c -I. var.c +cc -DUnix -c -I. havefork.c +cc -DUnix -c -I. unix.c +cc -DUnix -c -I. y.tab.c +cc -o rc code.o exec.o getflags.o glob.o here.o io.o lex.o pcmd.o pfnc.o simple.o subr.o trap.o tree.o var.o havefork.o unix.o y.tab.o --- /sys/src/cmd/rc/simple.c Thu Aug 14 20:36:23 2008 +++ /sys/src/cmd/rc/simple.c Fri Mar 1 22:29:17 2013 @@ -145,12 +145,31 @@ if(flag['i']!=0){ if(wdirfd==-2) /* try only once */ wdirfd = open("/dev/wdir", OWRITE|OCEXEC); - if(wdirfd>=0) + if(wdirfd>=0) { + fcntl(wdirfd, F_SETFD, FD_CLOEXEC); write(wdirfd, word, strlen(word)); + } } return 1; } +static char * +appfile(char *dir, char *comp) +{ + int dirlen, complen; + char *s, *p; + + dirlen = strlen(dir); + complen = strlen(comp); + s = emalloc(dirlen + 1 + complen + 1); + memmove(s, dir, dirlen); + p = s + dirlen; + *p++ = '/'; + memmove(p, comp, complen); + p[complen] = '\0'; + return s; +} + void execcd(void) { @@ -169,8 +188,7 @@ cdpath = &nullpath; for(; cdpath; cdpath = cdpath->next){ if(cdpath->word[0] != '\0') - dir = smprint("%s/%s", cdpath->word, - a->next->word); + dir = appfile(cdpath->word, a->next->word); else dir = strdup(a->next->word); @@ -360,7 +378,7 @@ fd = -1; for(path = searchpath(zero); path; path = path->next){ if(path->word[0] != '\0') - file = smprint("%s/%s", path->word, zero); + file = appfile(path->word, zero); else file = strdup(zero); @@ -477,8 +495,8 @@ for(path = searchpath(a->word); path; path = path->next){ if(path->word[0] != '\0') - file = smprint("%s/%s", - path->word, a->word); + file = appfile(path->word, + a->word); else file = strdup(a->word); if(Executable(file)){ --- /sys/src/cmd/rc/unix/havefork.c Thu Feb 28 21:33:17 2013 +++ /sys/src/cmd/rc/unix/havefork.c Thu Jan 1 01:00:00 1970 @@ -1,217 +0,0 @@ -#include "rc.h" -#include "getflags.h" -#include "exec.h" -#include "io.h" -#include "fns.h" - -int havefork = 1; - -void -Xasync(void) -{ - int null = open("/dev/null", 0); - int pid; - char npid[10]; - if(null<0){ - Xerror("Can't open /dev/null\n"); - return; - } -#ifdef Unix - pid = fork(); -#else - pid = rfork(RFFDG|RFPROC|RFNOTEG); -#endif - switch(pid){ - case -1: - close(null); - Xerror("try again"); - break; - case 0: - pushredir(ROPEN, null, 0); - start(runq->code, runq->pc+1, runq->local); - runq->ret = 0; - break; - default: - close(null); - runq->pc = runq->code[runq->pc].i; - inttoascii(npid, pid); - setvar("apid", newword(npid, (word *)0)); - break; - } -} - -void -Xpipe(void) -{ - struct thread *p = runq; - int pc = p->pc, forkid; - int lfd = p->code[pc++].i; - int rfd = p->code[pc++].i; - int pfd[2]; - if(pipe(pfd)<0){ - Xerror("can't get pipe"); - return; - } - switch(forkid = fork()){ - case -1: - Xerror("try again"); - break; - case 0: - start(p->code, pc+2, runq->local); - runq->ret = 0; - close(pfd[PRD]); - pushredir(ROPEN, pfd[PWR], lfd); - break; - default: - start(p->code, p->code[pc].i, runq->local); - close(pfd[PWR]); - pushredir(ROPEN, pfd[PRD], rfd); - p->pc = p->code[pc+1].i; - p->pid = forkid; - break; - } -} - -/* - * Who should wait for the exit from the fork? - */ -void -Xbackq(void) -{ - char wd[8193]; - int c; - char *s, *ewd=&wd[8192], *stop; - struct io *f; - var *ifs = vlook("ifs"); - word *v, *nextv; - int pfd[2]; - int pid; - stop = ifs->val?ifs->val->word:""; - if(pipe(pfd)<0){ - Xerror("can't make pipe"); - return; - } - switch(pid = fork()){ - case -1: - Xerror("try again"); - close(pfd[PRD]); - close(pfd[PWR]); - return; - case 0: - close(pfd[PRD]); - start(runq->code, runq->pc+1, runq->local); - pushredir(ROPEN, pfd[PWR], 1); - return; - default: - close(pfd[PWR]); - f = openfd(pfd[PRD]); - s = wd; - v = 0; - while((c = rchr(f))!=EOF){ - if(strchr(stop, c) || s==ewd){ - if(s!=wd){ - *s='\0'; - v = newword(wd, v); - s = wd; - } - } - else *s++=c; - } - if(s!=wd){ - *s='\0'; - v = newword(wd, v); - } - closeio(f); - Waitfor(pid, 0); - /* v points to reversed arglist -- reverse it onto argv */ - while(v){ - nextv = v->next; - v->next = runq->argv->words; - runq->argv->words = v; - v = nextv; - } - runq->pc = runq->code[runq->pc].i; - return; - } -} - -void -Xpipefd(void) -{ - struct thread *p = runq; - int pc = p->pc; - char name[40]; - int pfd[2]; - int sidefd, mainfd; - if(pipe(pfd)<0){ - Xerror("can't get pipe"); - return; - } - if(p->code[pc].i==READ){ - sidefd = pfd[PWR]; - mainfd = pfd[PRD]; - } - else{ - sidefd = pfd[PRD]; - mainfd = pfd[PWR]; - } - switch(fork()){ - case -1: - Xerror("try again"); - break; - case 0: - start(p->code, pc+2, runq->local); - close(mainfd); - pushredir(ROPEN, sidefd, p->code[pc].i==READ?1:0); - runq->ret = 0; - break; - default: - close(sidefd); - pushredir(ROPEN, mainfd, mainfd); /* isn't this a noop? */ - strcpy(name, Fdprefix); - inttoascii(name+strlen(name), mainfd); - pushword(name); - p->pc = p->code[pc+1].i; - break; - } -} - -void -Xsubshell(void) -{ - int pid; - switch(pid = fork()){ - case -1: - Xerror("try again"); - break; - case 0: - start(runq->code, runq->pc+1, runq->local); - runq->ret = 0; - break; - default: - Waitfor(pid, 1); - runq->pc = runq->code[runq->pc].i; - break; - } -} - -int -execforkexec(void) -{ - int pid; - int n; - char buf[ERRMAX]; - - switch(pid = fork()){ - case -1: - return -1; - case 0: - pushword("exec"); - execexec(); - strcpy(buf, "can't exec: "); - n = strlen(buf); - errstr(buf+n, ERRMAX-n); - Exit(buf); - } - return pid; -} --- /sys/src/cmd/rc/unix/include/bio.h Thu Feb 28 21:06:37 2013 +++ /sys/src/cmd/rc/unix/include/bio.h Thu Jan 1 01:00:00 1970 @@ -1,80 +0,0 @@ -#ifndef _BIOH_ -#define _BIOH_ 1 - -#include /* for off_t */ -#include /* for O_RDONLY, O_WRONLY */ - -typedef struct Biobuf Biobuf; - -enum -{ - Bsize = 8*1024, - Bungetsize = 4, /* space for ungetc */ - Bmagic = 0x314159, - Beof = -1, - Bbad = -2, - - Binactive = 0, /* states */ - Bractive, - Bwactive, - Bracteof, - - Bend -}; - -struct Biobuf -{ - int icount; /* neg num of bytes at eob */ - int ocount; /* num of bytes at bob */ - int rdline; /* num of bytes after rdline */ - int runesize; /* num of bytes of last getrune */ - int state; /* r/w/inactive */ - int fid; /* open file */ - int flag; /* magic if malloc'ed */ - off_t offset; /* offset of buffer in file */ - int bsize; /* size of buffer */ - unsigned char* bbuf; /* pointer to beginning of buffer */ - unsigned char* ebuf; /* pointer to end of buffer */ - unsigned char* gbuf; /* pointer to good data in buf */ - unsigned char b[Bungetsize+Bsize]; -}; - -#define BGETC(bp)\ - ((bp)->icount?(bp)->bbuf[(bp)->bsize+(bp)->icount++]:Bgetc((bp))) -#define BPUTC(bp,c)\ - ((bp)->ocount?(bp)->bbuf[(bp)->bsize+(bp)->ocount++]=(c),0:Bputc((bp),(c))) -#define BOFFSET(bp)\ - (((bp)->state==Bractive)?\ - (bp)->offset + (bp)->icount:\ - (((bp)->state==Bwactive)?\ - (bp)->offset + ((bp)->bsize + (bp)->ocount):\ - -1)) -#define BLINELEN(bp)\ - (bp)->rdline -#define BFILDES(bp)\ - (bp)->fid - -int Bbuffered(Biobuf*); -int Bfildes(Biobuf*); -int Bflush(Biobuf*); -int Bgetc(Biobuf*); -int Bgetd(Biobuf*, double*); -int Binit(Biobuf*, int, int); -int Binits(Biobuf*, int, int, unsigned char*, int); -int Blinelen(Biobuf*); -off_t Boffset(Biobuf*); -Biobuf* Bopen(char*, int); -int Bprint(Biobuf*, char*, ...); -int Bputc(Biobuf*, int); -void* Brdline(Biobuf*, int); -long Bread(Biobuf*, void*, long); -off_t Bseek(Biobuf*, off_t, int); -int Bterm(Biobuf*); -int Bungetc(Biobuf*); -long Bwrite(Biobuf*, void*, long); - -long Bgetrune(Biobuf*); -int Bputrune(Biobuf*, long); -int Bungetrune(Biobuf*); - -#endif --- /sys/src/cmd/rc/unix/include/fmt.h Thu Feb 28 21:06:37 2013 +++ /sys/src/cmd/rc/unix/include/fmt.h Thu Jan 1 01:00:00 1970 @@ -1,99 +0,0 @@ - -/* - * The authors of this software are Rob Pike and Ken Thompson. - * Copyright (c) 2002 by Lucent Technologies. - * Permission to use, copy, modify, and distribute this software for any - * purpose without fee is hereby granted, provided that this entire notice - * is included in all copies of any software which is or includes a copy - * or modification of this software and in all copies of the supporting - * documentation for such software. - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. - */ - -#ifndef _FMTH_ -#define _FMTH_ 1 - -#include - -#ifndef _UTFH_ -#include -#endif - -typedef struct Fmt Fmt; -struct Fmt{ - unsigned char runes; /* output buffer is runes or chars? */ - void *start; /* of buffer */ - void *to; /* current place in the buffer */ - void *stop; /* end of the buffer; overwritten if flush fails */ - int (*flush)(Fmt *); /* called when to == stop */ - void *farg; /* to make flush a closure */ - int nfmt; /* num chars formatted so far */ - va_list args; /* args passed to dofmt */ - int r; /* % format Rune */ - int width; - int prec; - unsigned long flags; -}; - -enum{ - FmtWidth = 1, - FmtLeft = FmtWidth << 1, - FmtPrec = FmtLeft << 1, - FmtSharp = FmtPrec << 1, - FmtSpace = FmtSharp << 1, - FmtSign = FmtSpace << 1, - FmtZero = FmtSign << 1, - FmtUnsigned = FmtZero << 1, - FmtShort = FmtUnsigned << 1, - FmtLong = FmtShort << 1, - FmtVLong = FmtLong << 1, - FmtComma = FmtVLong << 1, - FmtByte = FmtComma << 1, - FmtLDouble = FmtByte << 1, - - FmtFlag = FmtLDouble << 1 -}; - -extern int print(char*, ...); -extern char* seprint(char*, char*, char*, ...); -extern char* vseprint(char*, char*, char*, va_list); -extern int snprint(char*, int, char*, ...); -extern int vsnprint(char*, int, char*, va_list); -extern char* smprint(char*, ...); -extern char* vsmprint(char*, va_list); -extern int sprint(char*, char*, ...); -extern int fprint(int, char*, ...); -extern int vfprint(int, char*, va_list); - -extern int runesprint(Rune*, char*, ...); -extern int runesnprint(Rune*, int, char*, ...); -extern int runevsnprint(Rune*, int, char*, va_list); -extern Rune* runeseprint(Rune*, Rune*, char*, ...); -extern Rune* runevseprint(Rune*, Rune*, char*, va_list); -extern Rune* runesmprint(char*, ...); -extern Rune* runevsmprint(char*, va_list); - -extern int fmtfdinit(Fmt*, int, char*, int); -extern int fmtfdflush(Fmt*); -extern int fmtstrinit(Fmt*); -extern char* fmtstrflush(Fmt*); - -extern int quotestrfmt(Fmt *f); -extern void quotefmtinstall(void); -extern int (*fmtdoquote)(int); - - -extern int fmtinstall(int, int (*)(Fmt*)); -extern int dofmt(Fmt*, char*); -extern int fmtprint(Fmt*, char*, ...); -extern int fmtvprint(Fmt*, char*, va_list); -extern int fmtrune(Fmt*, int); -extern int fmtstrcpy(Fmt*, char*); - -extern double fmtstrtod(const char *, char **); -extern double fmtcharstod(int(*)(void*), void*); - -#endif --- /sys/src/cmd/rc/unix/include/lib9.h Thu Feb 28 21:28:44 2013 +++ /sys/src/cmd/rc/unix/include/lib9.h Thu Jan 1 01:00:00 1970 @@ -1,23 +0,0 @@ -#include -#include "utf.h" - -#define nil ((void*)0) - -#define uchar _fmtuchar -#define ushort _fmtushort -#define uint _fmtuint -#define ulong _fmtulong -#define vlong _fmtvlong -// #define uvlong _fmtuvlong - -typedef unsigned char uchar; -typedef unsigned short ushort; -typedef unsigned int uint; -typedef unsigned long ulong; - -typedef unsigned long long uvlong; - -#define OREAD O_RDONLY -#define OWRITE O_WRONLY -#define ORDWR O_RDWR -#define OCEXEC 0 --- /sys/src/cmd/rc/unix/include/regexp9.h Thu Feb 28 21:06:37 2013 +++ /sys/src/cmd/rc/unix/include/regexp9.h Thu Jan 1 01:00:00 1970 @@ -1,71 +0,0 @@ -#ifndef _REGEXP9H_ - -#define _REGEXP9H_ 1 -#include - -typedef struct Resub Resub; -typedef struct Reclass Reclass; -typedef struct Reinst Reinst; -typedef struct Reprog Reprog; - -/* - * Sub expression matches - */ -struct Resub{ - union - { - char *sp; - Rune *rsp; - }s; - union - { - char *ep; - Rune *rep; - }e; -}; - -/* - * character class, each pair of rune's defines a range - */ -struct Reclass{ - Rune *end; - Rune spans[64]; -}; - -/* - * Machine instructions - */ -struct Reinst{ - int type; - union { - Reclass *cp; /* class pointer */ - Rune r; /* character */ - int subid; /* sub-expression id for RBRA and LBRA */ - Reinst *right; /* right child of OR */ - }u1; - union { /* regexp relies on these two being in the same union */ - Reinst *left; /* left child of OR */ - Reinst *next; /* next instruction for CAT & LBRA */ - }u2; -}; - -/* - * Reprogram definition - */ -struct Reprog{ - Reinst *startinst; /* start pc */ - Reclass class[16]; /* .data */ - Reinst firstinst[5]; /* .text */ -}; - -extern Reprog *regcomp(char*); -extern Reprog *regcomplit(char*); -extern Reprog *regcompnl(char*); -extern void regerror(char*); -extern int regexec(Reprog*, char*, Resub*, int); -extern void regsub(char*, char*, int, Resub*, int); - -extern int rregexec(Reprog*, Rune*, Resub*, int); -extern void rregsub(Rune*, Rune*, Resub*, int); - -#endif --- /sys/src/cmd/rc/unix/include/utf.h Thu Feb 28 21:06:37 2013 +++ /sys/src/cmd/rc/unix/include/utf.h Thu Jan 1 01:00:00 1970 @@ -1,51 +0,0 @@ -#ifndef _UTFH_ -#define _UTFH_ 1 - -typedef unsigned short Rune; /* 16 bits */ - -enum -{ - UTFmax = 3, /* maximum bytes per rune */ - Runesync = 0x80, /* cannot represent part of a UTF sequence (<) */ - Runeself = 0x80, /* rune and UTF sequences are the same (<) */ - Runeerror = 0x80, /* decoding error in UTF */ -}; - -/* - * rune routines - */ -extern int runetochar(char*, Rune*); -extern int chartorune(Rune*, char*); -extern int runelen(long); -extern int runenlen(Rune*, int); -extern int fullrune(char*, int); -extern int utflen(char*); -extern int utfnlen(char*, long); -extern char* utfrune(char*, long); -extern char* utfrrune(char*, long); -extern char* utfutf(char*, char*); -extern char* utfecpy(char*, char*, char*); - -extern Rune* runestrcat(Rune*, Rune*); -extern Rune* runestrchr(Rune*, Rune); -extern int runestrcmp(Rune*, Rune*); -extern Rune* runestrcpy(Rune*, Rune*); -extern Rune* runestrncpy(Rune*, Rune*, long); -extern Rune* runestrecpy(Rune*, Rune*, Rune*); -extern Rune* runestrdup(Rune*); -extern Rune* runestrncat(Rune*, Rune*, long); -extern int runestrncmp(Rune*, Rune*, long); -extern Rune* runestrrchr(Rune*, Rune); -extern long runestrlen(Rune*); -extern Rune* runestrstr(Rune*, Rune*); - -extern Rune tolowerrune(Rune); -extern Rune totitlerune(Rune); -extern Rune toupperrune(Rune); -extern int isalpharune(Rune); -extern int islowerrune(Rune); -extern int isspacerune(Rune); -extern int istitlerune(Rune); -extern int isupperrune(Rune); - -#endif --- /sys/src/cmd/rc/unix/makefile Thu Feb 28 23:30:35 2013 +++ /sys/src/cmd/rc/unix/makefile Thu Jan 1 01:00:00 1970 @@ -1,64 +0,0 @@ -O=o -TARG=rc -COMMONOFILES=\ - code.$O\ - exec.$O\ - getflags.$O\ - glob.$O\ - here.$O\ - io.$O\ - lex.$O\ - pcmd.$O\ - pfnc.$O\ - simple.$O\ - subr.$O\ - trap.$O\ - tree.$O\ - var.$O\ - havefork.$O\ - -PLAN9OFILES=plan9.$O\ - -UNIXOFILES=unix.$O\ - -OFILES=$(COMMONOFILES) $(UNIXOFILES) y.tab.$O - -HFILES=rc.h\ - x.tab.h\ - io.h\ - exec.h\ - fns.h\ - -YFILES=syn.y - -BIN=/$objtype/bin - -UPDATE=\ - mkfile\ - $HFILES\ - ${COMMONOFILES:%.$O=%.c}\ - ${UNIXOFILES:%.$O=%.c}\ - ${PLAN9OFILES:%.$O=%.c}\ - $YFILES\ - ${TARG:%=/386/bin/%}\ - -CC=cc -CFLAGS= -c -w -Iinclude -LD=cc - -YFLAGS=-d -S - -rc: $(OFILES) - $(CC) -o rc $(OFILES) -x.tab.h: y.tab.h - cmp -s x.tab.h y.tab.h || cp y.tab.h x.tab.h - -clean: - rm -f [$OS].out *.[$OS] [xy].tab.? y.debug $TARG - -regress: $O.out - cd test - mk - -unregress: - for(test in test/*.test) rc $test >$test.out --- /sys/src/cmd/rc/unix/mkfile Thu Feb 28 21:53:07 2013 +++ /sys/src/cmd/rc/unix/mkfile Thu Jan 1 01:00:00 1970 @@ -1,68 +0,0 @@ -$test.out - -listing: - pr mkfile $HFILES $FILES $FILES9 $FILESUNIX $YFILES|lp -du --- /sys/src/cmd/rc/unix/rc.h Fri Mar 1 00:22:27 2013 +++ /sys/src/cmd/rc/unix/rc.h Thu Jan 1 01:00:00 1970 @@ -1,172 +0,0 @@ -/* - * Plan9 is defined for plan 9 - * Unix is defined for Unix - * Please don't litter the code with ifdefs. The two below should be enough. - */ -#define Unix -#ifdef Plan9 -#include -#include -#define NSIG 32 -#define SIGINT 2 -#define SIGQUIT 3 -#endif - -#ifdef Unix -#define _BSD_EXTENSION -#define _PLAN9_SOURCE -#define _POSIX_SOURCE -#define _RESEARCH_SOURCE -#define _SUSV2_SOURCE - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef NSIG -#define NSIG 32 -#endif - -#define uintptr uintptr_t -#endif - -#ifndef ERRMAX -#define ERRMAX 128 -#endif - -#define YYMAXDEPTH 500 -#ifndef PAREN -#include "x.tab.h" -#endif -typedef struct tree tree; -typedef struct word word; -typedef struct io io; -typedef union code code; -typedef struct var var; -typedef struct list list; -typedef struct redir redir; -typedef struct thread thread; -typedef struct builtin builtin; - -#ifdef Plan9 -#pragma incomplete word -#pragma incomplete io -#endif - -struct tree{ - int type; - int rtype, fd0, fd1; /* details of REDIR PIPE DUP tokens */ - char *str; - int quoted; - int iskw; - tree *child[3]; - tree *next; -}; -tree *newtree(void); -tree *token(char*, int), *klook(char*), *tree1(int, tree*); -tree *tree2(int, tree*, tree*), *tree3(int, tree*, tree*, tree*); -tree *mung1(tree*, tree*), *mung2(tree*, tree*, tree*); -tree *mung3(tree*, tree*, tree*, tree*), *epimung(tree*, tree*); -tree *simplemung(tree*), *heredoc(tree*); -void freetree(tree*); -tree *cmdtree; - -/* - * The first word of any code vector is a reference count. - * Always create a new reference to a code vector by calling codecopy(.). - * Always call codefree(.) when deleting a reference. - */ -union code{ - void (*f)(void); - int i; - char *s; -}; - -char *promptstr; -int doprompt; - -#define NTOK 8192 - -char tok[NTOK]; - -#define APPEND 1 -#define WRITE 2 -#define READ 3 -#define HERE 4 -#define DUPFD 5 -#define CLOSE 6 -#define RDWR 7 - -struct var{ - char *name; /* ascii name */ - word *val; /* value */ - int changed; - code *fn; /* pointer to function's code vector */ - int fnchanged; - int pc; /* pc of start of function */ - var *next; /* next on hash or local list */ -}; -var *vlook(char*), *gvlook(char*), *newvar(char*, var*); - -#define NVAR 521 - -var *gvar[NVAR]; /* hash for globals */ - -#define new(type) ((type *)emalloc(sizeof(type))) - -void *emalloc(long); -void *Malloc(ulong); -void efree(void *); - -#define NOFILE 128 /* should come from */ - -struct here{ - tree *tag; - char *name; - struct here *next; -}; -int mypid; - -/* - * Glob character escape in strings: - * In a string, GLOB must be followed by *?[ or GLOB. - * GLOB* matches any string - * GLOB? matches any single character - * GLOB[...] matches anything in the brackets - * GLOBGLOB matches GLOB - */ -#define GLOB ((char)0x01) -/* - * onebyte(c), twobyte(c), threebyte(c) - * Is c the first character of a one- two- or three-byte utf sequence? - */ -#define onebyte(c) ((c&0x80)==0x00) -#define twobyte(c) ((c&0xe0)==0xc0) -#define threebyte(c) ((c&0xf0)==0xe0) - -char **argp; -char **args; -int nerror; /* number of errors encountered during compilation */ -int doprompt; /* is it time for a prompt? */ -/* - * Which fds are the reading/writing end of a pipe? - * Unfortunately, this can vary from system to system. - * 9th edition Unix doesn't care, the following defines - * work on plan 9. - */ -#define PRD 0 -#define PWR 1 -char Rcmain[], Fdprefix[]; -/* - * How many dot commands have we executed? - * Used to ensure that -v flag doesn't print rcmain. - */ -int ndot; -char *getstatus(void); -int lastc; -int lastword; --- /sys/src/cmd/rc/unix/rcmain Thu Feb 28 23:27:18 2013 +++ /sys/src/cmd/rc/unix/rcmain Thu Jan 1 01:00:00 1970 @@ -1,34 +0,0 @@ -# rcmain: unix version -if(~ $#home 0) home=$HOME -if(~ $#ifs 0) ifs=' -' -switch($#prompt){ -case 0 - prompt=('% ' ' ') -case 1 - prompt=($prompt ' ') -} -if(~ $rcname ?.out) prompt=('broken! ' ' ') -if(flag p) path=/bin -if not { - finit - if(~ $#path 0) path=(. /bin /usr/bin /usr/local/bin) -} -fn sigexit -if(! ~ $#cflag 0){ - if(flag l && test -r $home/lib/profile) . $home/lib/profile - status='' - eval $cflag -} -if not if(flag i){ - if(flag l && test -r $home/lib/profile) . $home/lib/profile - status='' - if(! ~ $#* 0) . $* - . -i /dev/fd/0 -} -if not if(~ $#* 0) . /dev/fd/0 -if not{ - status='' - . $* -} -exit $status --- /sys/src/cmd/rc/unix/run Thu Feb 28 22:03:58 2013 +++ /sys/src/cmd/rc/unix/run Thu Jan 1 01:00:00 1970 @@ -1,20 +0,0 @@ -yacc -d syn.y -cmp -s x.tab.h y.tab.h || cp y.tab.h x.tab.h -cc -w -c -Iinclude code.c -cc -w -c -Iinclude exec.c -cc -w -c -Iinclude getflags.c -cc -w -c -Iinclude glob.c -cc -w -c -Iinclude here.c -cc -w -c -Iinclude io.c -cc -w -c -Iinclude lex.c -cc -w -c -Iinclude pcmd.c -cc -w -c -Iinclude pfnc.c -cc -w -c -Iinclude simple.c -cc -w -c -Iinclude subr.c -cc -w -c -Iinclude trap.c -cc -w -c -Iinclude tree.c -cc -w -c -Iinclude var.c -cc -w -c -Iinclude havefork.c -cc -w -c -Iinclude unix.c -cc -w -c -Iinclude y.tab.c -cc -o rc code.o exec.o getflags.o glob.o here.o io.o lex.o pcmd.o pfnc.o simple.o subr.o trap.o tree.o var.o havefork.o unix.o y.tab.o --- /sys/src/cmd/rc/unix/simple.c Thu Feb 28 23:36:07 2013 +++ /sys/src/cmd/rc/unix/simple.c Thu Jan 1 01:00:00 1970 @@ -1,508 +0,0 @@ -/* - * Maybe `simple' is a misnomer. - */ -#include "rc.h" -#include "getflags.h" -#include "exec.h" -#include "io.h" -#include "fns.h" -/* - * Search through the following code to see if we're just going to exit. - */ -int -exitnext(void){ - union code *c=&runq->code[runq->pc]; - while(c->f==Xpopredir) c++; - return c->f==Xexit; -} - -void -Xsimple(void) -{ - word *a; - thread *p = runq; - var *v; - struct builtin *bp; - int pid; - globlist(); - a = runq->argv->words; - if(a==0){ - Xerror1("empty argument list"); - return; - } - if(flag['x']) - pfmt(err, "%v\n", p->argv->words); /* wrong, should do redirs */ - v = gvlook(a->word); - if(v->fn) - execfunc(v); - else{ - if(strcmp(a->word, "builtin")==0){ - if(count(a)==1){ - pfmt(err, "builtin: empty argument list\n"); - setstatus("empty arg list"); - poplist(); - return; - } - a = a->next; - popword(); - } - for(bp = Builtin;bp->name;bp++) - if(strcmp(a->word, bp->name)==0){ - (*bp->fnc)(); - return; - } - if(exitnext()){ - /* fork and wait is redundant */ - pushword("exec"); - execexec(); - Xexit(); - } - else{ - flush(err); - Updenv(); /* necessary so changes don't go out again */ - if((pid = execforkexec()) < 0){ - Xerror("try again"); - return; - } - - /* interrupts don't get us out */ - poplist(); - while(Waitfor(pid, 1) < 0) - ; - } - } -} -struct word nullpath = { "", 0}; - -void -doredir(redir *rp) -{ - if(rp){ - doredir(rp->next); - switch(rp->type){ - case ROPEN: - if(rp->from!=rp->to){ - Dup(rp->from, rp->to); - close(rp->from); - } - break; - case RDUP: - Dup(rp->from, rp->to); - break; - case RCLOSE: - close(rp->from); - break; - } - } -} - -word* -searchpath(char *w) -{ - word *path; - if(strncmp(w, "/", 1)==0 - || strncmp(w, "#", 1)==0 - || strncmp(w, "./", 2)==0 - || strncmp(w, "../", 3)==0 - || (path = vlook("path")->val)==0) - path=&nullpath; - return path; -} - -void -execexec(void) -{ - popword(); /* "exec" */ - if(runq->argv->words==0){ - Xerror1("empty argument list"); - return; - } - doredir(runq->redir); - Execute(runq->argv->words, searchpath(runq->argv->words->word)); - poplist(); -} - -void -execfunc(var *func) -{ - word *starval; - popword(); - starval = runq->argv->words; - runq->argv->words = 0; - poplist(); - start(func->fn, func->pc, runq->local); - runq->local = newvar(strdup("*"), runq->local); - runq->local->val = starval; - runq->local->changed = 1; -} - -int -dochdir(char *word) -{ - /* report to /dev/wdir if it exists and we're interactive */ - static int wdirfd = -2; - if(chdir(word)<0) return -1; - if(flag['i']!=0){ - if(wdirfd==-2) /* try only once */ - wdirfd = open("/dev/wdir", OWRITE|OCEXEC); - if(wdirfd>=0) { -#ifdef Unix - fcntl(wdirfd, F_SETFD, FD_CLOEXEC); -#endif - write(wdirfd, word, strlen(word)); - } - } - return 1; -} - -void -execcd(void) -{ - word *a = runq->argv->words; - word *cdpath; - char dir[512]; - setstatus("can't cd"); - cdpath = vlook("cdpath")->val; - switch(count(a)){ - default: - pfmt(err, "Usage: cd [directory]\n"); - break; - case 2: - if(a->next->word[0]=='/' || cdpath==0) - cdpath=&nullpath; - for(;cdpath;cdpath = cdpath->next){ - strcpy(dir, cdpath->word); - if(dir[0]) - strcat(dir, "/"); - strcat(dir, a->next->word); - if(dochdir(dir)>=0){ - if(strlen(cdpath->word) - && strcmp(cdpath->word, ".")!=0) - pfmt(err, "%s\n", dir); - setstatus(""); - break; - } - } - if(cdpath==0) - pfmt(err, "Can't cd %s: %r\n", a->next->word); - break; - case 1: - a = vlook("home")->val; - if(count(a)>=1){ - if(dochdir(a->word)>=0) - setstatus(""); - else - pfmt(err, "Can't cd %s: %r\n", a->word); - } - else - pfmt(err, "Can't cd -- $home empty\n"); - break; - } - poplist(); -} - -void -execexit(void) -{ - switch(count(runq->argv->words)){ - default: - pfmt(err, "Usage: exit [status]\nExiting anyway\n"); - case 2: - setstatus(runq->argv->words->next->word); - case 1: Xexit(); - } -} - -void -execshift(void) -{ - int n; - word *a; - var *star; - switch(count(runq->argv->words)){ - default: - pfmt(err, "Usage: shift [n]\n"); - setstatus("shift usage"); - poplist(); - return; - case 2: - n = atoi(runq->argv->words->next->word); - break; - case 1: - n = 1; - break; - } - star = vlook("*"); - for(;n && star->val;--n){ - a = star->val->next; - efree(star->val->word); - efree((char *)star->val); - star->val = a; - star->changed = 1; - } - setstatus(""); - poplist(); -} - -int -octal(char *s) -{ - int n = 0; - while(*s==' ' || *s=='\t' || *s=='\n') s++; - while('0'<=*s && *s<='7') n = n*8+*s++-'0'; - return n; -} - -int -mapfd(int fd) -{ - redir *rp; - for(rp = runq->redir;rp;rp = rp->next){ - switch(rp->type){ - case RCLOSE: - if(rp->from==fd) - fd=-1; - break; - case RDUP: - case ROPEN: - if(rp->to==fd) - fd = rp->from; - break; - } - } - return fd; -} -union code rdcmds[4]; - -void -execcmds(io *f) -{ - static int first = 1; - if(first){ - rdcmds[0].i = 1; - rdcmds[1].f = Xrdcmds; - rdcmds[2].f = Xreturn; - first = 0; - } - start(rdcmds, 1, runq->local); - runq->cmdfd = f; - runq->iflast = 0; -} - -void -execeval(void) -{ - char *cmdline, *s, *t; - int len = 0; - word *ap; - if(count(runq->argv->words)<=1){ - Xerror1("Usage: eval cmd ..."); - return; - } - eflagok = 1; - for(ap = runq->argv->words->next;ap;ap = ap->next) - len+=1+strlen(ap->word); - cmdline = emalloc(len); - s = cmdline; - for(ap = runq->argv->words->next;ap;ap = ap->next){ - for(t = ap->word;*t;) *s++=*t++; - *s++=' '; - } - s[-1]='\n'; - poplist(); - execcmds(opencore(cmdline, len)); - efree(cmdline); -} -union code dotcmds[14]; - -void -execdot(void) -{ - int iflag = 0; - int fd; - list *av; - thread *p = runq; - char *zero; - static int first = 1; - char file[512]; - word *path; - if(first){ - dotcmds[0].i = 1; - dotcmds[1].f = Xmark; - dotcmds[2].f = Xword; - dotcmds[3].s="0"; - dotcmds[4].f = Xlocal; - dotcmds[5].f = Xmark; - dotcmds[6].f = Xword; - dotcmds[7].s="*"; - dotcmds[8].f = Xlocal; - dotcmds[9].f = Xrdcmds; - dotcmds[10].f = Xunlocal; - dotcmds[11].f = Xunlocal; - dotcmds[12].f = Xreturn; - first = 0; - } - else - eflagok = 1; - popword(); - if(p->argv->words && strcmp(p->argv->words->word, "-i")==0){ - iflag = 1; - popword(); - } - /* get input file */ - if(p->argv->words==0){ - Xerror1("Usage: . [-i] file [arg ...]"); - return; - } - zero = strdup(p->argv->words->word); - popword(); - fd=-1; - for(path = searchpath(zero);path;path = path->next){ - strcpy(file, path->word); - if(file[0]) - strcat(file, "/"); - strcat(file, zero); - if((fd = open(file, 0))>=0) break; - if(strcmp(file, "/dev/stdin")==0){ /* for sun & ucb */ - fd = Dup1(0); - if(fd>=0) - break; - } - } - if(fd<0){ - pfmt(err, "%s: ", zero); - setstatus("can't open"); - Xerror(".: can't open"); - return; - } - /* set up for a new command loop */ - start(dotcmds, 1, (struct var *)0); - pushredir(RCLOSE, fd, 0); - runq->cmdfile = zero; - runq->cmdfd = openfd(fd); - runq->iflag = iflag; - runq->iflast = 0; - /* push $* value */ - pushlist(); - runq->argv->words = p->argv->words; - /* free caller's copy of $* */ - av = p->argv; - p->argv = av->next; - efree((char *)av); - /* push $0 value */ - pushlist(); - pushword(zero); - ndot++; -} - -void -execflag(void) -{ - char *letter, *val; - switch(count(runq->argv->words)){ - case 2: - setstatus(flag[runq->argv->words->next->word[0]]?"":"flag not set"); - break; - case 3: - letter = runq->argv->words->next->word; - val = runq->argv->words->next->next->word; - if(strlen(letter)==1){ - if(strcmp(val, "+")==0){ - flag[(uchar)letter[0]] = flagset; - break; - } - if(strcmp(val, "-")==0){ - flag[(uchar)letter[0]] = 0; - break; - } - } - default: - Xerror1("Usage: flag [letter] [+-]"); - return; - } - poplist(); -} - -void -execwhatis(void){ /* mildly wrong -- should fork before writing */ - word *a, *b, *path; - var *v; - struct builtin *bp; - char file[512]; - struct io out[1]; - int found, sep; - a = runq->argv->words->next; - if(a==0){ - Xerror1("Usage: whatis name ..."); - return; - } - setstatus(""); - out->fd = mapfd(1); - out->bufp = out->buf; - out->ebuf = &out->buf[NBUF]; - out->strp = 0; - for(;a;a = a->next){ - v = vlook(a->word); - if(v->val){ - pfmt(out, "%s=", a->word); - if(v->val->next==0) - pfmt(out, "%q\n", v->val->word); - else{ - sep='('; - for(b = v->val;b && b->word;b = b->next){ - pfmt(out, "%c%q", sep, b->word); - sep=' '; - } - pfmt(out, ")\n"); - } - found = 1; - } - else - found = 0; - v = gvlook(a->word); - if(v->fn) - pfmt(out, "fn %s %s\n", v->name, v->fn[v->pc-1].s); - else{ - for(bp = Builtin;bp->name;bp++) - if(strcmp(a->word, bp->name)==0){ - pfmt(out, "builtin %s\n", a->word); - break; - } - if(!bp->name){ - for(path = searchpath(a->word);path;path = path->next){ - strcpy(file, path->word); - if(file[0]) - strcat(file, "/"); - strcat(file, a->word); - if(Executable(file)){ - pfmt(out, "%s\n", file); - break; - } - } - if(!path && !found){ - pfmt(err, "%s: not found\n", a->word); - setstatus("not found"); - } - } - } - } - poplist(); - flush(err); -} - -void -execwait(void) -{ - switch(count(runq->argv->words)){ - default: - Xerror1("Usage: wait [pid]"); - return; - case 2: - Waitfor(atoi(runq->argv->words->next->word), 0); - break; - case 1: - Waitfor(-1, 0); - break; - } - poplist(); -} --- /sys/src/cmd/rc/unix/words Fri Mar 1 00:33:38 2013 +++ /sys/src/cmd/rc/unix/words Thu Jan 1 01:00:00 1970 @@ -1,8 +0,0 @@ -How to build rc on unix: - -ramfs -dircp .. /tmp -cd /tmp/unix -dircp . .. -cd .. -run --- /sys/src/cmd/rc/unix.c Fri Mar 1 00:21:28 2013 +++ /sys/src/cmd/rc/unix.c Fri Mar 1 23:25:23 2013 @@ -9,8 +9,8 @@ #include "getflags.h" #include -char Rcmain[]="/usr/lib/rcmain"; -char Fdprefix[]="/dev/fd/"; +char *Rcmain = "/usr/lib/rcmain"; +char *Fdprefix = "/dev/fd/"; void execfinit(void); @@ -542,5 +542,51 @@ return 1; if(strchr("`^#*[]=|\\?${}()'<>&;", c)) return 1; + return 0; +} + +int +rfork(int bits) +{ + return fork(); +} + +int *waitpids; +int nwaitpids; + +void +addwaitpid(int pid) +{ + waitpids = realloc(waitpids, (nwaitpids+1)*sizeof waitpids[0]); + if(waitpids == 0) + panic("Can't realloc %d waitpids", nwaitpids+1); + waitpids[nwaitpids++] = pid; +} + +void +delwaitpid(int pid) +{ + int r, w; + + for(r=w=0; r +#include +#include +#include +#include +#include +#include + +#ifndef NSIG +#define NSIG 32 +#endif + +/* plan 9 compatibility */ +#define RFPROC 1 +#define RFFDG 1 +#define RFNOTEG 1 + +#define uintptr uintptr_t + +char *strdup(const char *); + +#define nil ((void*)0) + +/* in case uchar, etc. are built-in types */ +#define uchar _fmtuchar +#define ushort _fmtushort +#define uint _fmtuint +#define ulong _fmtulong +#define vlong _fmtvlong +#define uvlong _fmtuvlong + +typedef unsigned char uchar; +typedef unsigned short ushort; +typedef unsigned int uint; +typedef unsigned long ulong; +typedef unsigned long long uvlong; + +#define OREAD O_RDONLY +#define OWRITE O_WRONLY +#define ORDWR O_RDWR +#define OCEXEC 0 --- /sys/src/cmd/rc/win32.c Mon Jul 7 00:33:01 2008 +++ /sys/src/cmd/rc/win32.c Fri Mar 1 20:53:47 2013 @@ -24,8 +24,9 @@ "term", 0 }; -char Rcmain[]="/rc/lib/rcmain"; -char Fdprefix[]="/fd/"; +char *Rcmain = "/rc/lib/rcmain"; +char *Fdprefix = "/fd/"; + void execfinit(void); void execbind(void); --- /sys/src/cmd/vc/gc.h Fri Mar 9 04:56:41 2012 +++ /sys/src/cmd/vc/gc.h Mon Mar 4 22:15:21 2013 @@ -267,7 +267,6 @@ int mulcon(Node*, Node*); Multab* mulcon0(long); void nullwarn(Node*, Node*); -void sextern(Sym*, Node*, long, long); void gextern(Sym*, Node*, long, long); void outcode(void); void ieeedtod(Ieee*, double); --- /sys/src/cmd/vc/swt.c Wed Feb 20 03:38:53 2013 +++ /sys/src/cmd/vc/swt.c Mon Mar 4 22:15:20 2013 @@ -19,7 +19,7 @@ if(nc < 5) { for(i=0; ival); gmove(nodconst(q->val), tn); gopcode(OEQ, n, tn, Z); @@ -32,7 +32,7 @@ } i = nc / 2; r = q+i; - if(debug['W']) + if(debug['K']) print("case > %.8llux\n", r->val); gmove(nodconst(r->val), tn); gopcode(OLT, tn, n, Z); @@ -41,7 +41,7 @@ patch(p, r->label); swit2(q, i, def, n, tn); - if(debug['W']) + if(debug['K']) print("case < %.8llux\n", r->val); patch(sp, pc); swit2(r+1, nc-i-1, def, n, tn); @@ -231,23 +231,6 @@ } p += 2; goto loop; -} - -void -sextern(Sym *s, Node *a, long o, long w) -{ - long e, lw; - - for(e=0; efrom.offset += o+e; - p->reg = lw; - p->to.type = D_SCONST; - memmove(p->to.sval, a->cstring+e, lw); - } } void --- /sys/src/libmach/map.c Fri Jul 22 21:45:01 2011 +++ /sys/src/libmach/map.c Sat Mar 2 00:23:59 2013 @@ -84,7 +84,6 @@ int fd; Map *map; uvlong n; - int mode; map = newmap(0, 4); if (!map) @@ -93,10 +92,11 @@ regs = "kregs"; else regs = "regs"; - mode = ORDWR; if (mach->regsize) { sprint(buf, "/proc/%d/%s", pid, regs); - fd = open(buf, mode); + fd = open(buf, ORDWR); + if(fd < 0) + fd = open(buf, OREAD); if(fd < 0) { free(map); return 0; @@ -105,7 +105,9 @@ } if (mach->fpregsize) { sprint(buf, "/proc/%d/fpregs", pid); - fd = open(buf, mode); + fd = open(buf, ORDWR); + if(fd < 0) + fd = open(buf, OREAD); if(fd < 0) { close(map->seg[0].fd); free(map);