9 /* -------- io.c -------- */
16 static struct iobuf sharedbuf = {AFID_NOBUF};
17 static struct iobuf mainbuf = {AFID_NOBUF};
18 static unsigned bufid = AFID_ID; /* buffer id counter */
20 struct ioarg temparg = {0, 0, 0, AFID_NOBUF, 0};
22 _PROTOTYPE(static void readhere, (char **name, char *s, int ec ));
23 _PROTOTYPE(void pushio, (struct ioarg *argp, int (*fn)()));
24 _PROTOTYPE(static int xxchar, (struct ioarg *ap ));
25 _PROTOTYPE(void tempname, (char *tname ));
33 if(e.linep > elinep) {
34 while((c=readc()) != '\n' && c)
36 err("input line too long");
41 if (ec != '\'' && e.iop->task != XGRAVE) {
44 if (c == '\n' && ec != '\"')
56 if (e.iop >= e.iobase)
64 return e.iop < e.iobase || (e.iop->peekc == 0 && e.iop->prev == 0);
72 for (; e.iop >= e.iobase; e.iop--)
73 if ((c = e.iop->peekc) != '\0') {
78 if (e.iop->prev != 0) {
79 if ((c = (*e.iop->iofn)(e.iop->argp, e.iop)) != '\0') {
86 return(e.iop->prev = c);
88 else if (e.iop->task == XIO && e.iop->prev != '\n') {
95 if (e.iop->task == XIO) {
97 return e.iop->prev = 0;
98 if (talking && e.iop == iostack+1)
102 if (e.iop >= iostack)
113 write(2, &c, sizeof c);
121 if (++e.iop >= &iostack[NPUSH]) {
123 err("Shell input nested too deeply");
129 if (argp->afid != AFID_NOBUF)
132 e.iop->argp = ioargstack + (e.iop - iostack);
133 *e.iop->argp = *argp;
134 e.iop->argp->afbuf = e.iop == &iostack[0] ? &mainbuf : &sharedbuf;
135 if (isatty(e.iop->argp->afile) == 0 &&
136 (e.iop == &iostack[0] ||
137 lseek(e.iop->argp->afile, 0L, 1) != -1)) {
138 if (++bufid == AFID_NOBUF)
140 e.iop->argp->afid = bufid;
148 if (fn == filechar || fn == linechar)
150 else if (fn == gravechar || fn == qgravechar)
151 e.iop->task = XGRAVE;
153 e.iop->task = XOTHER;
160 register struct io *xp;
168 * Input generating functions
172 * Produce the characters of a string, then a newline, then EOF.
176 register struct ioarg *ap;
180 if (ap->aword == NULL)
182 if ((c = *ap->aword++) == 0) {
190 * Given a list of words, produce the characters
191 * in them, with a space after each word.
195 register struct ioarg *ap;
200 if ((wl = ap->awordlist) == NULL)
203 if ((c = *(*wl)++) != 0)
208 ap->awordlist = NULL;
213 * Return the characters of a list of words,
214 * producing a space between them.
218 register struct ioarg *ap;
222 if ((wp = *ap->awordlist++) != NULL) {
223 PUSHIO(aword, wp, *ap->awordlist == NULL? strchar: xxchar);
231 register struct ioarg *ap;
235 if (ap->aword == NULL)
237 if ((c = *ap->aword++) == '\0') {
245 * Produce the characters from a single word (string).
249 register struct ioarg *ap;
253 if (ap->aword == NULL || (c = *ap->aword++) == 0)
259 * Produce quoted characters from a single word (string).
263 register struct ioarg *ap;
267 if (ap->aword == NULL || (c = *ap->aword++) == 0)
273 * Return the characters from a file.
277 register struct ioarg *ap;
281 struct iobuf *bp = ap->afbuf;
283 if (ap->afid != AFID_NOBUF) {
284 if ((i = ap->afid != bp->id) || bp->bufp == bp->ebufp) {
286 lseek(ap->afile, ap->afpos, 0);
288 i = read(ap->afile, bp->buf, sizeof(bp->buf));
289 } while (i < 0 && errno == EINTR);
295 bp->ebufp = (bp->bufp = bp->buf) + i;
298 return *bp->bufp++ & 0177;
302 i = read(ap->afile, &c, sizeof(c));
303 } while (i < 0 && errno == EINTR);
304 return(i == sizeof(c)? c&0177: (closef(ap->afile), 0));
308 * Return the characters from a here temp file.
312 register struct ioarg *ap;
317 if (read(ap->afile, &c, sizeof(c)) != sizeof(c)) {
326 * Return the characters produced by a process (`...`).
327 * Quote them if required, and remove any trailing newline characters.
336 if ((c = qgravechar(ap, iop)&~QUOTE) == '\n')
343 register struct ioarg *ap;
355 } else if ((c = filechar(ap)) == '\n') {
357 while ((c = filechar(ap)) == '\n')
365 return(c!=0? c|QUOTE: 0);
369 * Return a single command (usually the first line) from a file.
373 register struct ioarg *ap;
377 if ((c = filechar(ap)) == '\n') {
380 ap->afile = -1; /* illegal value */
391 write(2, s, strlen(s));
398 write(2, &c, sizeof c);
421 for (u=NUFILE; u<NOFILE;)
426 * remap fd into Shell's fd space
436 for (i=0; i<NOFILE; i++)
441 } while (fd >= 0 && fd < e.iofd);
442 for (i=0; i<NOFILE; i++)
446 err("too many files open in shell");
457 if ((i = pipe(pv)) < 0)
458 err("can't create pipe - try again");
472 /* -------- here.c -------- */
473 /* #include "sh.h" */
482 struct ioword *h_iop;
486 static struct here *inhere; /* list of hear docs while parsing */
487 static struct here *acthere; /* list of active here documents */
494 register struct here *h, *lh;
496 h = (struct here *) space(sizeof(struct here));
499 h->h_tag = evalstr(s, DOSUB);
508 for (lh = inhere; lh!=NULL; lh = lh->h_next)
509 if (lh->h_next == 0) {
513 iop->io_flag |= IOHERE|IOXHERE;
514 for (s = h->h_tag; *s; s++)
516 iop->io_flag &= ~ IOXHERE;
519 h->h_dosub = iop->io_flag & IOXHERE;
525 register struct here *h, *hp;
527 /* Scan here files first leaving inhere list in place */
528 for (hp = h = inhere; h != NULL; hp = h, h = h->h_next)
529 readhere(&h->h_iop->io_name, h->h_tag, h->h_dosub? 0: '\'');
531 /* Make inhere list active - keep list intact for scraphere */
533 hp->h_next = acthere;
540 readhere(name, s, ec)
549 char line [LINELIM+1];
553 *name = strsave(tname, areanum);
554 tf = creat(tname, 0600);
557 if (newenv(setjmp(errpt = ev)) != 0)
560 pushio(e.iop->argp, e.iop->iofn);
563 if (talking && e.iop <= iostack)
566 while ((c = getc(ec)) != '\n' && c) {
569 if (next >= &line[LINELIM]) {
576 if (strcmp(s, line) == 0 || c == 0)
579 write (tf, line, (int)(next-line));
582 prs("here document `"); prs(s); err("' unclosed");
590 * open here temp file.
591 * if unquoted here, expand here temp file into second temp file.
611 if ((tf = creat(tname, 0600)) < 0)
613 if (newenv(setjmp(errpt = ev)) == 0) {
614 PUSHIO(afile, hf, herechar);
616 while ((c = subgetc(0, 0)) != 0) {
618 write(tf, &c, sizeof c);
634 register struct here *h;
636 for (h = inhere; h != NULL; h = h->h_next) {
637 if (h->h_iop && h->h_iop->io_name)
638 unlink(h->h_iop->io_name);
643 /* unlink here temp files before a freearea(area) */
648 register struct here *h, *hl;
651 for (h = acthere; h != NULL; h = h->h_next)
652 if (getarea((char *) h) >= area) {
653 if (h->h_iop->io_name != NULL)
654 unlink(h->h_iop->io_name);
658 hl->h_next = h->h_next;
668 register char *cp, *lp;
670 for (cp = tname, lp = "/tmp/shtm"; (*cp = *lp++) != '\0'; cp++)
672 lp = putn(getpid()*1000 + inc++);
673 for (; (*cp = *lp++) != '\0'; cp++)