paradis@encore.UUCP (Jim Paradis) (06/23/87)
Here and in the next six messages are my fixes for the MINIX shell. These patches fix the following bugs: - Allows you to build the shell under MINIX (yay!) - Re-implements "<<" input redirection in a non-memory-hogging way - $0 now returns the name of the shell script rather than "/bin/sh" - $# now returns the correct number of arguments - Backslashes inside of double quotes are no longer swallowed. This first article contains a new file, "shg.c". The reason for this is that, in order to get the shell to build under MINIX it is necessary to do all the external variable declarations properly (i.e. declare them for real only once and extern for all other uses). To do this I changed all the "extern"s in sh.h to "Extern". For all other files, "Extern" is declared to be "extern". To accomplish the "real" declaration of the variables, though, shg.c defines "Extern" to be the null string, then includes "sh.h". You should add "shg.c" to your commands makefile. The next six articles are diff-patches to sh.h, sh1.c, sh2.c, sh3.c, sh4.c, and sh5.c respectively. +----------------+ Jim Paradis linus--+ +--+-------------+ | Encore Computer Corp. necntc--| | | E N C O R E | | 257 Cedar Hill St. ihnp4--+-encore!paradis | +-------------+--+ Marlboro MA 01752 decvax--| +----------------+ (617) 460-0500 talcott--+ ------------------------------cut here ------------------------------ /* This is file shg.c */ #define Extern #include <signal.h> #include <errno.h> #include <setjmp.h> #include "sh.h"
paradis@encore.UUCP (Jim Paradis) (06/23/87)
Apply this patch to sh.h -------------------------cut here------------------------------ 88,95c88,95 < char **dolv; < int dolc; < int exstat; < char gflg; < int talking; /* interactive (talking-type wireless) */ < int execflg; < int multiline; /* \n changed to ; */ < struct op *outtree; /* result from parser */ --- > Extern char **dolv; > Extern int dolc; > Extern int exstat; > Extern char gflg; > Extern int talking; /* interactive (talking-type wireless) */ > Extern int execflg; > Extern int multiline; /* \n changed to ; */ > Extern struct op *outtree; /* result from parser */ 97,98c97,98 < xint *failpt; < xint *errpt; --- > Extern xint *failpt; > Extern xint *errpt; 103,104c103,105 < } *brklist; < int isbreak; --- > } ; > Extern struct brkcon *brklist; > Extern int isbreak; 127,128c128,129 < struct wdblock *wdlist; < struct wdblock *iolist; --- > Extern struct wdblock *wdlist; > Extern struct wdblock *iolist; 152c153 < char *flag; --- > extern char *flag; 154,155c155,156 < char *null; /* null value for variable */ < int intr; /* interrupt pending */ --- > extern char *null; /* null value for variable */ > extern int intr; /* interrupt pending */ 157,159c158,160 < char *trap[NSIG]; < char ourtrap[NSIG]; < int trapset; /* trap pending */ --- > Extern char *trap[NSIG]; > Extern char ourtrap[NSIG]; > Extern int trapset; /* trap pending */ 161c162 < int inword; /* defer traps and interrupts */ --- > extern int inword; /* defer traps and interrupts */ 163c164 < int yynerrs; /* yacc */ --- > Extern int yynerrs; /* yacc */ 165,166c166,167 < char line[LINELIM]; < char *elinep; --- > Extern char line[LINELIM]; > extern char *elinep; 219c220 < struct var *vlist; /* dictionary */ --- > Extern struct var *vlist; /* dictionary */ 221,226c222,227 < struct var *homedir; /* home directory */ < struct var *prompt; /* main prompt */ < struct var *cprompt; /* continuation prompt */ < struct var *path; /* search path for commands */ < struct var *shell; /* shell to interpret command files */ < struct var *ifs; /* field separators */ --- > Extern struct var *homedir; /* home directory */ > Extern struct var *prompt; /* main prompt */ > Extern struct var *cprompt; /* continuation prompt */ > Extern struct var *path; /* search path for commands */ > Extern struct var *shell; /* shell to interpret command files */ > Extern struct var *ifs; /* field separators */ 256c257 < struct io iostack[NPUSH]; --- > Extern struct io iostack[NPUSH]; 260c261,263 < #define XIO 3 /* file IO */ --- > #define XIO 4 /* file IO */ > #define XHERE 0x80 /* Any of the above inside a here document */ > #define XMASK 0x7f /* Get the actual task */ 263c266 < #define INSUB() (e.iop->task == XGRAVE || e.iop->task == XDOLL) --- > #define INSUB() ((e.iop->task&XMASK)==XGRAVE||(e.iop->task&XMASK)==XDOLL) 300c303 < struct ioarg temparg; /* temporary for PUSHIO */ --- > Extern struct ioarg temparg; /* temporary for PUSHIO */ 330c333 < int areanum; /* current allocation area */ --- > Extern int areanum; /* current allocation area */
paradis@encore.UUCP (Jim Paradis) (06/23/87)
Apply this patch to sh1.c -----------------------cut here---------------------------- 0a1 > #define Extern extern 21c22 < char **environ; /* environment pointer */ --- > extern char **environ; /* environment pointer */ 132c133 < if (newfile(*++argv)) --- > if (newfile(*++argv)) { 133a135 > } 163c165 < setval(lookup("#"), putn(dolc)); --- > setval(lookup("#"), putn(dolc-1));
paradis@encore.UUCP (Jim Paradis) (06/23/87)
Apply this patch to sh2.c ---------------------------cut here----------------------------- 0a1 > #define Extern extern 70a72 > 71a74 > 82a86 > 104a109 > 122a128 > 124a131 >
paradis@encore.UUCP (Jim Paradis) (06/23/87)
Apply this patch to sh3.c -------------------------------cut here------------------------- 0a1 > #define Extern extern 269c270 < if (t->type == TPAREN) --- > if (t->type == TPAREN) { 270a272 > } 275c277 < if (wp[0] == NULL) --- > if (wp[0] == NULL) { 276a279 > } 526a530,534 > > /* If the file is not executable (i.e. doesn't > * have a valid a.out header) then try it as a > * shell script. > */ 529,530c537,538 < *v = "/bin/sh"; < execve(*v, v, envp); --- > *v = e.linep; > execve("/bin/sh", v, envp);
paradis@encore.UUCP (Jim Paradis) (06/23/87)
Apply this patch to sh4.c -------------------------cut here---------------------------- 0a1 > #define Extern extern 234c235 < e.iop->task = XOTHER; --- > e.iop->task = XOTHER; 320c321 < for (cp = e.iop->arg.aword; *cp != '`'; cp++) --- > for (cp = e.iop->arg.aword; *cp != '`'; cp++) { 324a326,327 > } > 348a352,355 > > /* jrp debug */ > scraphere(); > 353a361 > 355a364 >
paradis@encore.UUCP (Jim Paradis) (06/23/87)
Apply this patch to sh5.c Strip the "|"s out from in front of this one first... I tried to post it but inews thought I was including too much text (grrrrrrrr!) ----------------------------cut here------------------------------ |0a1 |> #define Extern extern |28c29 |< if (ec != '\'') { |--- |> if ((ec != '"') && (ec != '\'')) { |84a86 |> |101a104 |> |128c131 |< if (ap->aword == NULL) |--- |> if (ap->aword == NULL) { |129a133 |> } |402d405 |< char *memcpy(); |416c419 |< char *b_start; |--- |> char *b_linebuf; |418,419c421,422 |< char *b_line; |< int b_size; |--- |> char b_tmpfile[50]; |> int b_fd; |424c427 |< #define NCPB 100 /* here text block allocation unit */ |--- |> #define NCPB 2048 /* here text block allocation unit */ |438a442 |> h->h_iop->io_un.io_here = NULL; |461,462c465,469 |< for (h = herelist; h != NULL; h = h->h_next) |< h->h_iop->io_un.io_here = readhere(h->h_tag, h->h_dosub? 0: '\''); |--- |> for (h = herelist; h != NULL; h = h->h_next) { |> h->h_iop->io_un.io_here = |> readhere(h->h_tag, h->h_dosub? 0: '\'', |> h->h_iop->io_flag & IOXHERE); |> } |467c474 |< readhere(s, ec) |--- |> readhere(s, ec, nolit) |476a484,488 |> bp->b_linebuf = (char *)space(NCPB); |> if (bp->b_linebuf == 0) { |> /* jrp - should release bp here... */ |> return(0); |> } |482,485c494,499 |< bp->b_size = 0; |< bp->b_line = 0; |< bp->b_next = 0; |< bp->b_start = 0; |--- |> |> /* jrp changes */ |> bp->b_linebuf[0] = 0; |> bp->b_next = bp->b_linebuf; |> bp->b_tmpfile[0] = 0; |> bp->b_fd = -1; |490c504 |< if (savec(c, bp) == 0) { |--- |> if (savec(c, bp, nolit) == 0) { |495,496c509,510 |< savec(0, bp); |< if (strcmp(s, bp->b_line) == 0 || c == 0) |--- |> savec(0, bp, nolit); |> if (strcmp(s, bp->b_linebuf) == 0 || c == 0) |498,499c512 |< bp->b_next[-1] = '\n'; |< bp->b_line = bp->b_next; |--- |> savec('\n', bp, nolit); |501c514 |< *bp->b_line = 0; |--- |> *bp->b_linebuf = 0; |511c524 |< savec(c, bp) |--- |> savec(c, bp, nolit) |514c527,535 |< register char *np; |--- |> /* jrp - gutted routine completely, modified to use temp file. */ |> |> /* If the file is not open, see if a filename needs to be |> * created. If so, create one. Then create the file. |> */ |> char * lp; |> char * cp; |> static int inc; |> int len; |516,525c537,561 |< if (bp->b_start == NULL || bp->b_next+1 >= bp->b_start+bp->b_size) { |< np = space(bp->b_size + NCPB); |< if (np == 0) |< return(0); |< memcpy(np, bp->b_start, bp->b_size); |< bp->b_size += NCPB; |< bp->b_line = np + (bp->b_line-bp->b_start); |< bp->b_next = np + (bp->b_next-bp->b_start); |< xfree(bp->b_start); |< bp->b_start = np; |--- |> if(bp->b_fd < 0) { |> if(bp->b_tmpfile[0] == 0) { |> /* Key this by the PID plus a tag... */ |> for (cp = bp->b_tmpfile, lp = "/tmp/shtm"; |> (*cp = *lp++) != '\0'; cp++) |> ; |> |> inc = (inc + 1) % 100; |> lp = putn(getpid()*100 + inc); |> for (; (*cp = *lp++) != '\0'; cp++) |> ; |> } |> |> /* Create the file, then open it for |> * read/write access. After opening the |> * file, unlink it to it'll go away when |> * we're through using it. |> */ |> bp->b_fd = creat(bp->b_tmpfile, 0600); |> close(bp->b_fd); |> bp->b_fd = open(bp->b_tmpfile, 2); |> unlink(bp->b_tmpfile); |> if(bp->b_fd < 0) { |> return(0); |> } |527,528c563,589 |< *bp->b_next++ = c; |< return(1); |--- |> |> /* Stuff the character into the line buffer. If it's a |> * newline, then insert it before the trailing null, write |> * out the line, and reset the line buffer. |> */ |> if(c == '\n') { |> bp->b_next[-1] = '\n'; |> bp->b_next[0] = '\0'; |> len = strlen(bp->b_linebuf); |> |> /* Write this out, unless the line ended |> * with a backslash... |> */ |> if((len > 1) && (bp->b_next[-2] != '\\')) { |> write_linebuf(bp, nolit); |> } |> |> return(1); |> } |> else { |> if(bp->b_next == &(bp->b_linebuf[NCPB - 1])) { |> prs("here: line buffer full\n"); |> return(0); |> } |> *(bp->b_next++) = c; |> return(1); |> } |530a592,620 |> write_linebuf(bp, nolit) |> struct block * bp; |> { |> |> char c; |> jmp_buf ev; |> |> if(nolit) { |> if (newenv(setjmp(errpt = ev)) == 0) { |> PUSHIO(aword, bp->b_linebuf, strchar); |> setbase(e.iop); |> e.iop->task |= XHERE; |> while ((c = subgetc(0, 0)) != 0) { |> c &= ~ QUOTE; |> write(bp->b_fd, &c, sizeof c); |> } |> quitenv(); |> |> } |> } |> else { |> write(bp->b_fd, bp->b_linebuf, strlen(bp->b_linebuf)); |> } |> |> /* Zap the line buffer for next time... */ |> bp->b_next = bp->b_linebuf; |> bp->b_linebuf[0] = 0; |> } |> |534,537c624 |< register tf; |< char tname[50]; |< static int inc; |< register char *cp, *lp; |--- |> int ret_fd; |541,549d627 |< for (cp = tname, lp = "/tmp/shtm"; (*cp = *lp++) != '\0'; cp++) |< ; |< lp = putn(getpid()*100 + inc++); |< for (; (*cp = *lp++) != '\0'; cp++) |< ; |< if ((tf = creat(tname, 0666)) >= 0) { |< if (xdoll) { |< char c; |< jmp_buf ev; |551,565c629,631 |< if (newenv(setjmp(errpt = ev)) == 0) { |< PUSHIO(aword, bp->b_start, strchar); |< setbase(e.iop); |< while ((c = subgetc(0, 0)) != 0) { |< c &= ~ QUOTE; |< write(tf, &c, sizeof c); |< } |< quitenv(); |< } else |< unlink(tname); |< } else |< write(tf, bp->b_start, bp->b_line-bp->b_start); |< close(tf); |< tf = open(tname, 0); |< unlink(tname); |--- |> /* If we have a temp file, then rewind it to the beginning */ |> if(bp->b_fd < 0) { |> return(-1); |567c633,642 |< return(tf); |--- |> |> lseek(bp->b_fd, 0L, 0); |> |> /* Free up this block pointer, as we're |> * not going to need it anymore. |> */ |> xfree(bp->b_linebuf); |> xfree(bp); |> |> return(bp->b_fd); |571a647,669 |> struct here * h; |> struct here * nexth; |> struct block * bp; |> |> |> /* Close and unlink any files associated with |> * heres in progress, and free up all the |> * associated structures. |> */ |> h = herelist; |> while(h != NULL) { |> nexth = h->h_next; |> bp = (struct block *)h->h_iop->io_un.io_here; |> if(bp != NULL) { |> if(bp->b_fd >= 0) { close(bp->b_fd); } |> if(*bp->b_tmpfile) { unlink(bp->b_tmpfile); } |> xfree(bp->b_linebuf); |> xfree(bp); |> } |> xfree(h); |> h = nexth; |> } |>