172339Sabial#define Extern extern 272339Sabial#include <sys/types.h> 372339Sabial#include <signal.h> 472339Sabial#define _NSIG NSIG 572339Sabial#include <errno.h> 672339Sabial#include <setjmp.h> 772339Sabial#include "sh.h" 872339Sabial 972339Sabial/* -------- io.c -------- */ 1072339Sabial/* #include "sh.h" */ 1172339Sabial 1272339Sabial/* 1372339Sabial * shell IO 1472339Sabial */ 1572339Sabial 1672339Sabialstatic struct iobuf sharedbuf = {AFID_NOBUF}; 1772339Sabialstatic struct iobuf mainbuf = {AFID_NOBUF}; 1872339Sabialstatic unsigned bufid = AFID_ID; /* buffer id counter */ 1972339Sabial 2072339Sabialstruct ioarg temparg = {0, 0, 0, AFID_NOBUF, 0}; 2172339Sabial 2272339Sabial_PROTOTYPE(static void readhere, (char **name, char *s, int ec )); 2372339Sabial_PROTOTYPE(void pushio, (struct ioarg *argp, int (*fn)())); 2472339Sabial_PROTOTYPE(static int xxchar, (struct ioarg *ap )); 2572339Sabial_PROTOTYPE(void tempname, (char *tname )); 2672339Sabial 2772339Sabialint 2872339Sabialgetc(ec) 2972339Sabialregister int ec; 3072339Sabial{ 3172339Sabial register int c; 3272339Sabial 3372339Sabial if(e.linep > elinep) { 3472339Sabial while((c=readc()) != '\n' && c) 3572339Sabial ; 3672339Sabial err("input line too long"); 3772339Sabial gflg++; 3872339Sabial return(c); 3972339Sabial } 4072339Sabial c = readc(); 4172339Sabial if (ec != '\'' && e.iop->task != XGRAVE) { 4272339Sabial if(c == '\\') { 4372339Sabial c = readc(); 4472339Sabial if (c == '\n' && ec != '\"') 4572339Sabial return(getc(ec)); 4672339Sabial c |= QUOTE; 4772339Sabial } 4872339Sabial } 4972339Sabial return(c); 5072339Sabial} 5172339Sabial 5272339Sabialvoid 5372339Sabialunget(c) 5472339Sabialint c; 5572339Sabial{ 5672339Sabial if (e.iop >= e.iobase) 5772339Sabial e.iop->peekc = c; 5872339Sabial} 5972339Sabial 6072339Sabialint 6172339Sabialeofc() 6272339Sabial 6372339Sabial{ 6472339Sabial return e.iop < e.iobase || (e.iop->peekc == 0 && e.iop->prev == 0); 6572339Sabial} 6672339Sabial 6772339Sabialint 6872339Sabialreadc() 6972339Sabial{ 7072339Sabial register c; 7172339Sabial 7272339Sabial for (; e.iop >= e.iobase; e.iop--) 7372339Sabial if ((c = e.iop->peekc) != '\0') { 7472339Sabial e.iop->peekc = 0; 7572339Sabial return(c); 7672339Sabial } 7772339Sabial else { 7872339Sabial if (e.iop->prev != 0) { 7972339Sabial if ((c = (*e.iop->iofn)(e.iop->argp, e.iop)) != '\0') { 8072339Sabial if (c == -1) { 8172339Sabial e.iop++; 8272339Sabial continue; 8372339Sabial } 8472339Sabial if (e.iop == iostack) 8572339Sabial ioecho(c); 8672339Sabial return(e.iop->prev = c); 8772339Sabial } 8872339Sabial else if (e.iop->task == XIO && e.iop->prev != '\n') { 8972339Sabial e.iop->prev = 0; 9072339Sabial if (e.iop == iostack) 9172339Sabial ioecho('\n'); 9272339Sabial return '\n'; 9372339Sabial } 9472339Sabial } 9572339Sabial if (e.iop->task == XIO) { 9672339Sabial if (multiline) 9772339Sabial return e.iop->prev = 0; 9872339Sabial if (talking && e.iop == iostack+1) 9972339Sabial prs(prompt->value); 10072339Sabial } 10172339Sabial } 10272339Sabial if (e.iop >= iostack) 10372339Sabial return(0); 10472339Sabial leave(); 10572339Sabial /* NOTREACHED */ 10672339Sabial} 10772339Sabial 10872339Sabialvoid 10972339Sabialioecho(c) 11072339Sabialchar c; 11172339Sabial{ 11272339Sabial if (flag['v']) 11372339Sabial write(2, &c, sizeof c); 11472339Sabial} 11572339Sabial 11672339Sabialvoid 11772339Sabialpushio(argp, fn) 11872339Sabialstruct ioarg *argp; 11972339Sabialint (*fn)(); 12072339Sabial{ 12172339Sabial if (++e.iop >= &iostack[NPUSH]) { 12272339Sabial e.iop--; 12372339Sabial err("Shell input nested too deeply"); 12472339Sabial gflg++; 12572339Sabial return; 12672339Sabial } 12772339Sabial e.iop->iofn = fn; 12872339Sabial 12972339Sabial if (argp->afid != AFID_NOBUF) 13072339Sabial e.iop->argp = argp; 13172339Sabial else { 13272339Sabial e.iop->argp = ioargstack + (e.iop - iostack); 13372339Sabial *e.iop->argp = *argp; 13472339Sabial e.iop->argp->afbuf = e.iop == &iostack[0] ? &mainbuf : &sharedbuf; 13572339Sabial if (isatty(e.iop->argp->afile) == 0 && 13672339Sabial (e.iop == &iostack[0] || 13772339Sabial lseek(e.iop->argp->afile, 0L, 1) != -1)) { 13872339Sabial if (++bufid == AFID_NOBUF) 13972339Sabial bufid = AFID_ID; 14072339Sabial e.iop->argp->afid = bufid; 14172339Sabial } 14272339Sabial } 14372339Sabial 14472339Sabial e.iop->prev = ~'\n'; 14572339Sabial e.iop->peekc = 0; 14672339Sabial e.iop->xchar = 0; 14772339Sabial e.iop->nlcount = 0; 14872339Sabial if (fn == filechar || fn == linechar) 14972339Sabial e.iop->task = XIO; 15072339Sabial else if (fn == gravechar || fn == qgravechar) 15172339Sabial e.iop->task = XGRAVE; 15272339Sabial else 15372339Sabial e.iop->task = XOTHER; 15472339Sabial} 15572339Sabial 15672339Sabialstruct io * 15772339Sabialsetbase(ip) 15872339Sabialstruct io *ip; 15972339Sabial{ 16072339Sabial register struct io *xp; 16172339Sabial 16272339Sabial xp = e.iobase; 16372339Sabial e.iobase = ip; 16472339Sabial return(xp); 16572339Sabial} 16672339Sabial 16772339Sabial/* 16872339Sabial * Input generating functions 16972339Sabial */ 17072339Sabial 17172339Sabial/* 17272339Sabial * Produce the characters of a string, then a newline, then EOF. 17372339Sabial */ 17472339Sabialint 17572339Sabialnlchar(ap) 17672339Sabialregister struct ioarg *ap; 17772339Sabial{ 17872339Sabial register int c; 17972339Sabial 18072339Sabial if (ap->aword == NULL) 18172339Sabial return(0); 18272339Sabial if ((c = *ap->aword++) == 0) { 18372339Sabial ap->aword = NULL; 18472339Sabial return('\n'); 18572339Sabial } 18672339Sabial return(c); 18772339Sabial} 18872339Sabial 18972339Sabial/* 19072339Sabial * Given a list of words, produce the characters 19172339Sabial * in them, with a space after each word. 19272339Sabial */ 19372339Sabialint 19472339Sabialwdchar(ap) 19572339Sabialregister struct ioarg *ap; 19672339Sabial{ 19772339Sabial register char c; 19872339Sabial register char **wl; 19972339Sabial 20072339Sabial if ((wl = ap->awordlist) == NULL) 20172339Sabial return(0); 20272339Sabial if (*wl != NULL) { 20372339Sabial if ((c = *(*wl)++) != 0) 20472339Sabial return(c & 0177); 20572339Sabial ap->awordlist++; 20672339Sabial return(' '); 20772339Sabial } 20872339Sabial ap->awordlist = NULL; 20972339Sabial return('\n'); 21072339Sabial} 21172339Sabial 21272339Sabial/* 21372339Sabial * Return the characters of a list of words, 21472339Sabial * producing a space between them. 21572339Sabial */ 21672339Sabialint 21772339Sabialdolchar(ap) 21872339Sabialregister struct ioarg *ap; 21972339Sabial{ 22072339Sabial register char *wp; 22172339Sabial 22272339Sabial if ((wp = *ap->awordlist++) != NULL) { 22372339Sabial PUSHIO(aword, wp, *ap->awordlist == NULL? strchar: xxchar); 22472339Sabial return(-1); 22572339Sabial } 22672339Sabial return(0); 22772339Sabial} 22872339Sabial 22972339Sabialstatic int 23072339Sabialxxchar(ap) 23172339Sabialregister struct ioarg *ap; 23272339Sabial{ 23372339Sabial register int c; 23472339Sabial 23572339Sabial if (ap->aword == NULL) 23672339Sabial return(0); 23772339Sabial if ((c = *ap->aword++) == '\0') { 23872339Sabial ap->aword = NULL; 23972339Sabial return(' '); 24072339Sabial } 24172339Sabial return(c); 24272339Sabial} 24372339Sabial 24472339Sabial/* 24572339Sabial * Produce the characters from a single word (string). 24672339Sabial */ 24772339Sabialint 24872339Sabialstrchar(ap) 24972339Sabialregister struct ioarg *ap; 25072339Sabial{ 25172339Sabial register int c; 25272339Sabial 25372339Sabial if (ap->aword == NULL || (c = *ap->aword++) == 0) 25472339Sabial return(0); 25572339Sabial return(c); 25672339Sabial} 25772339Sabial 25872339Sabial/* 25972339Sabial * Produce quoted characters from a single word (string). 26072339Sabial */ 26172339Sabialint 26272339Sabialqstrchar(ap) 26372339Sabialregister struct ioarg *ap; 26472339Sabial{ 26572339Sabial register int c; 26672339Sabial 26772339Sabial if (ap->aword == NULL || (c = *ap->aword++) == 0) 26872339Sabial return(0); 26972339Sabial return(c|QUOTE); 27072339Sabial} 27172339Sabial 27272339Sabial/* 27372339Sabial * Return the characters from a file. 27472339Sabial */ 27572339Sabialint 27672339Sabialfilechar(ap) 27772339Sabialregister struct ioarg *ap; 27872339Sabial{ 27972339Sabial register int i; 28072339Sabial char c; 28172339Sabial struct iobuf *bp = ap->afbuf; 28272339Sabial 28372339Sabial if (ap->afid != AFID_NOBUF) { 28472339Sabial if ((i = ap->afid != bp->id) || bp->bufp == bp->ebufp) { 28572339Sabial if (i) 28672339Sabial lseek(ap->afile, ap->afpos, 0); 28772339Sabial do { 28872339Sabial i = read(ap->afile, bp->buf, sizeof(bp->buf)); 28972339Sabial } while (i < 0 && errno == EINTR); 29072339Sabial if (i <= 0) { 29172339Sabial closef(ap->afile); 29272339Sabial return 0; 29372339Sabial } 29472339Sabial bp->id = ap->afid; 29572339Sabial bp->ebufp = (bp->bufp = bp->buf) + i; 29672339Sabial } 29772339Sabial ap->afpos++; 29872339Sabial return *bp->bufp++ & 0177; 29972339Sabial } 30072339Sabial 30172339Sabial do { 30272339Sabial i = read(ap->afile, &c, sizeof(c)); 30372339Sabial } while (i < 0 && errno == EINTR); 30472339Sabial return(i == sizeof(c)? c&0177: (closef(ap->afile), 0)); 30572339Sabial} 30672339Sabial 30772339Sabial/* 30872339Sabial * Return the characters from a here temp file. 30972339Sabial */ 31072339Sabialint 31172339Sabialherechar(ap) 31272339Sabialregister struct ioarg *ap; 31372339Sabial{ 31472339Sabial char c; 31572339Sabial 31672339Sabial 31772339Sabial if (read(ap->afile, &c, sizeof(c)) != sizeof(c)) { 31872339Sabial close(ap->afile); 31972339Sabial c = 0; 32072339Sabial } 32172339Sabial return (c); 32272339Sabial 32372339Sabial} 32472339Sabial 32572339Sabial/* 32672339Sabial * Return the characters produced by a process (`...`). 32772339Sabial * Quote them if required, and remove any trailing newline characters. 32872339Sabial */ 32972339Sabialint 33072339Sabialgravechar(ap, iop) 33172339Sabialstruct ioarg *ap; 33272339Sabialstruct io *iop; 33372339Sabial{ 33472339Sabial register int c; 33572339Sabial 33672339Sabial if ((c = qgravechar(ap, iop)&~QUOTE) == '\n') 33772339Sabial c = ' '; 33872339Sabial return(c); 33972339Sabial} 34072339Sabial 34172339Sabialint 34272339Sabialqgravechar(ap, iop) 34372339Sabialregister struct ioarg *ap; 34472339Sabialstruct io *iop; 34572339Sabial{ 34672339Sabial register int c; 34772339Sabial 34872339Sabial if (iop->xchar) { 34972339Sabial if (iop->nlcount) { 35072339Sabial iop->nlcount--; 35172339Sabial return('\n'|QUOTE); 35272339Sabial } 35372339Sabial c = iop->xchar; 35472339Sabial iop->xchar = 0; 35572339Sabial } else if ((c = filechar(ap)) == '\n') { 35672339Sabial iop->nlcount = 1; 35772339Sabial while ((c = filechar(ap)) == '\n') 35872339Sabial iop->nlcount++; 35972339Sabial iop->xchar = c; 36072339Sabial if (c == 0) 36172339Sabial return(c); 36272339Sabial iop->nlcount--; 36372339Sabial c = '\n'; 36472339Sabial } 36572339Sabial return(c!=0? c|QUOTE: 0); 36672339Sabial} 36772339Sabial 36872339Sabial/* 36972339Sabial * Return a single command (usually the first line) from a file. 37072339Sabial */ 37172339Sabialint 37272339Sabiallinechar(ap) 37372339Sabialregister struct ioarg *ap; 37472339Sabial{ 37572339Sabial register int c; 37672339Sabial 37772339Sabial if ((c = filechar(ap)) == '\n') { 37872339Sabial if (!multiline) { 37972339Sabial closef(ap->afile); 38072339Sabial ap->afile = -1; /* illegal value */ 38172339Sabial } 38272339Sabial } 38372339Sabial return(c); 38472339Sabial} 38572339Sabial 38672339Sabialvoid 38772339Sabialprs(s) 38872339Sabialregister char *s; 38972339Sabial{ 39072339Sabial if (*s) 39172339Sabial write(2, s, strlen(s)); 39272339Sabial} 39372339Sabial 39472339Sabialvoid 39572339Sabialputc(c) 39672339Sabialchar c; 39772339Sabial{ 39872339Sabial write(2, &c, sizeof c); 39972339Sabial} 40072339Sabial 40172339Sabialvoid 40272339Sabialprn(u) 40372339Sabialunsigned u; 40472339Sabial{ 40572339Sabial prs(itoa(u, 0)); 40672339Sabial} 40772339Sabial 40872339Sabialvoid 40972339Sabialclosef(i) 41072339Sabialregister int i; 41172339Sabial{ 41272339Sabial if (i > 2) 41372339Sabial close(i); 41472339Sabial} 41572339Sabial 41672339Sabialvoid 41772339Sabialcloseall() 41872339Sabial{ 41972339Sabial register u; 42072339Sabial 42172339Sabial for (u=NUFILE; u<NOFILE;) 42272339Sabial close(u++); 42372339Sabial} 42472339Sabial 42572339Sabial/* 42672339Sabial * remap fd into Shell's fd space 42772339Sabial */ 42872339Sabialint 42972339Sabialremap(fd) 43072339Sabialregister int fd; 43172339Sabial{ 43272339Sabial register int i; 43372339Sabial int map[NOFILE]; 43472339Sabial 43572339Sabial if (fd < e.iofd) { 43672339Sabial for (i=0; i<NOFILE; i++) 43772339Sabial map[i] = 0; 43872339Sabial do { 43972339Sabial map[fd] = 1; 44072339Sabial fd = dup(fd); 44172339Sabial } while (fd >= 0 && fd < e.iofd); 44272339Sabial for (i=0; i<NOFILE; i++) 44372339Sabial if (map[i]) 44472339Sabial close(i); 44572339Sabial if (fd < 0) 44672339Sabial err("too many files open in shell"); 44772339Sabial } 44872339Sabial return(fd); 44972339Sabial} 45072339Sabial 45172339Sabialint 45272339Sabialopenpipe(pv) 45372339Sabialregister int *pv; 45472339Sabial{ 45572339Sabial register int i; 45672339Sabial 45772339Sabial if ((i = pipe(pv)) < 0) 45872339Sabial err("can't create pipe - try again"); 45972339Sabial return(i); 46072339Sabial} 46172339Sabial 46272339Sabialvoid 46372339Sabialclosepipe(pv) 46472339Sabialregister int *pv; 46572339Sabial{ 46672339Sabial if (pv != NULL) { 46772339Sabial close(*pv++); 46872339Sabial close(*pv); 46972339Sabial } 47072339Sabial} 47172339Sabial 47272339Sabial/* -------- here.c -------- */ 47372339Sabial/* #include "sh.h" */ 47472339Sabial 47572339Sabial/* 47672339Sabial * here documents 47772339Sabial */ 47872339Sabial 47972339Sabialstruct here { 48072339Sabial char *h_tag; 48172339Sabial int h_dosub; 48272339Sabial struct ioword *h_iop; 48372339Sabial struct here *h_next; 48472339Sabial}; 48572339Sabial 48672339Sabialstatic struct here *inhere; /* list of hear docs while parsing */ 48772339Sabialstatic struct here *acthere; /* list of active here documents */ 48872339Sabial 48972339Sabialvoid 49072339Sabialmarkhere(s, iop) 49172339Sabialregister char *s; 49272339Sabialstruct ioword *iop; 49372339Sabial{ 49472339Sabial register struct here *h, *lh; 49572339Sabial 49672339Sabial h = (struct here *) space(sizeof(struct here)); 49772339Sabial if (h == 0) 49872339Sabial return; 49972339Sabial h->h_tag = evalstr(s, DOSUB); 50072339Sabial if (h->h_tag == 0) 50172339Sabial return; 50272339Sabial h->h_iop = iop; 50372339Sabial iop->io_name = 0; 50472339Sabial h->h_next = NULL; 50572339Sabial if (inhere == 0) 50672339Sabial inhere = h; 50772339Sabial else 50872339Sabial for (lh = inhere; lh!=NULL; lh = lh->h_next) 50972339Sabial if (lh->h_next == 0) { 51072339Sabial lh->h_next = h; 51172339Sabial break; 51272339Sabial } 51372339Sabial iop->io_flag |= IOHERE|IOXHERE; 51472339Sabial for (s = h->h_tag; *s; s++) 51572339Sabial if (*s & QUOTE) { 51672339Sabial iop->io_flag &= ~ IOXHERE; 51772339Sabial *s &= ~ QUOTE; 51872339Sabial } 51972339Sabial h->h_dosub = iop->io_flag & IOXHERE; 52072339Sabial} 52172339Sabial 52272339Sabialvoid 52372339Sabialgethere() 52472339Sabial{ 52572339Sabial register struct here *h, *hp; 52672339Sabial 52772339Sabial /* Scan here files first leaving inhere list in place */ 52872339Sabial for (hp = h = inhere; h != NULL; hp = h, h = h->h_next) 52972339Sabial readhere(&h->h_iop->io_name, h->h_tag, h->h_dosub? 0: '\''); 53072339Sabial 53172339Sabial /* Make inhere list active - keep list intact for scraphere */ 53272339Sabial if (hp != NULL) { 53372339Sabial hp->h_next = acthere; 53472339Sabial acthere = inhere; 53572339Sabial inhere = NULL; 53672339Sabial } 53772339Sabial} 53872339Sabial 53972339Sabialstatic void 54072339Sabialreadhere(name, s, ec) 54172339Sabialchar **name; 54272339Sabialregister char *s; 54372339Sabialint ec; 54472339Sabial{ 54572339Sabial int tf; 54672339Sabial char tname[30]; 54772339Sabial register c; 54872339Sabial jmp_buf ev; 54972339Sabial char line [LINELIM+1]; 55072339Sabial char *next; 55172339Sabial 55272339Sabial tempname(tname); 55372339Sabial *name = strsave(tname, areanum); 55472339Sabial tf = creat(tname, 0600); 55572339Sabial if (tf < 0) 55672339Sabial return; 55772339Sabial if (newenv(setjmp(errpt = ev)) != 0) 55872339Sabial unlink(tname); 55972339Sabial else { 56072339Sabial pushio(e.iop->argp, e.iop->iofn); 56172339Sabial e.iobase = e.iop; 56272339Sabial for (;;) { 56372339Sabial if (talking && e.iop <= iostack) 56472339Sabial prs(cprompt->value); 56572339Sabial next = line; 56672339Sabial while ((c = getc(ec)) != '\n' && c) { 56772339Sabial if (ec == '\'') 56872339Sabial c &= ~ QUOTE; 56972339Sabial if (next >= &line[LINELIM]) { 57072339Sabial c = 0; 57172339Sabial break; 57272339Sabial } 57372339Sabial *next++ = c; 57472339Sabial } 57572339Sabial *next = 0; 57672339Sabial if (strcmp(s, line) == 0 || c == 0) 57772339Sabial break; 57872339Sabial *next++ = '\n'; 57972339Sabial write (tf, line, (int)(next-line)); 58072339Sabial } 58172339Sabial if (c == 0) { 58272339Sabial prs("here document `"); prs(s); err("' unclosed"); 58372339Sabial } 58472339Sabial quitenv(); 58572339Sabial } 58672339Sabial close(tf); 58772339Sabial} 58872339Sabial 58972339Sabial/* 59072339Sabial * open here temp file. 59172339Sabial * if unquoted here, expand here temp file into second temp file. 59272339Sabial */ 59372339Sabialint 59472339Sabialherein(hname, xdoll) 59572339Sabialchar *hname; 59672339Sabialint xdoll; 59772339Sabial{ 59872339Sabial register hf, tf; 59972339Sabial 60072339Sabial if (hname == 0) 60172339Sabial return(-1); 60272339Sabial hf = open(hname, 0); 60372339Sabial if (hf < 0) 60472339Sabial return (-1); 60572339Sabial if (xdoll) { 60672339Sabial char c; 60772339Sabial char tname[30]; 60872339Sabial jmp_buf ev; 60972339Sabial 61072339Sabial tempname(tname); 61172339Sabial if ((tf = creat(tname, 0600)) < 0) 61272339Sabial return (-1); 61372339Sabial if (newenv(setjmp(errpt = ev)) == 0) { 61472339Sabial PUSHIO(afile, hf, herechar); 61572339Sabial setbase(e.iop); 61672339Sabial while ((c = subgetc(0, 0)) != 0) { 61772339Sabial c &= ~ QUOTE; 61872339Sabial write(tf, &c, sizeof c); 61972339Sabial } 62072339Sabial quitenv(); 62172339Sabial } else 62272339Sabial unlink(tname); 62372339Sabial close(tf); 62472339Sabial tf = open(tname, 0); 62572339Sabial unlink(tname); 62672339Sabial return (tf); 62772339Sabial } else 62872339Sabial return (hf); 62972339Sabial} 63072339Sabial 63172339Sabialvoid 63272339Sabialscraphere() 63372339Sabial{ 63472339Sabial register struct here *h; 63572339Sabial 63672339Sabial for (h = inhere; h != NULL; h = h->h_next) { 63772339Sabial if (h->h_iop && h->h_iop->io_name) 63872339Sabial unlink(h->h_iop->io_name); 63972339Sabial } 64072339Sabial inhere = NULL; 64172339Sabial} 64272339Sabial 64372339Sabial/* unlink here temp files before a freearea(area) */ 64472339Sabialvoid 64572339Sabialfreehere(area) 64672339Sabialint area; 64772339Sabial{ 64872339Sabial register struct here *h, *hl; 64972339Sabial 65072339Sabial hl = NULL; 65172339Sabial for (h = acthere; h != NULL; h = h->h_next) 65272339Sabial if (getarea((char *) h) >= area) { 65372339Sabial if (h->h_iop->io_name != NULL) 65472339Sabial unlink(h->h_iop->io_name); 65572339Sabial if (hl == NULL) 65672339Sabial acthere = h->h_next; 65772339Sabial else 65872339Sabial hl->h_next = h->h_next; 65972339Sabial } else 66072339Sabial hl = h; 66172339Sabial} 66272339Sabial 66372339Sabialvoid 66472339Sabialtempname(tname) 66572339Sabialchar *tname; 66672339Sabial{ 66772339Sabial static int inc; 66872339Sabial register char *cp, *lp; 66972339Sabial 67072339Sabial for (cp = tname, lp = "/tmp/shtm"; (*cp = *lp++) != '\0'; cp++) 67172339Sabial ; 67272339Sabial lp = putn(getpid()*1000 + inc++); 67372339Sabial for (; (*cp = *lp++) != '\0'; cp++) 67472339Sabial ; 67572339Sabial} 676