682 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			682 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
#define Extern extern
 | 
						|
#include <sys/types.h>
 | 
						|
#include <signal.h>
 | 
						|
#include <errno.h>
 | 
						|
#include <setjmp.h>
 | 
						|
#include "sh.h"
 | 
						|
 | 
						|
/* -------- io.c -------- */
 | 
						|
/* #include "sh.h" */
 | 
						|
 | 
						|
/*
 | 
						|
 * shell IO
 | 
						|
 */
 | 
						|
 | 
						|
static struct iobuf sharedbuf = {AFID_NOBUF};
 | 
						|
static struct iobuf mainbuf = {AFID_NOBUF};
 | 
						|
static unsigned bufid = AFID_ID;	/* buffer id counter */
 | 
						|
 | 
						|
struct ioarg temparg = {0, 0, 0, AFID_NOBUF, 0};
 | 
						|
 | 
						|
_PROTOTYPE(static void readhere, (char **name, char *s, int ec ));
 | 
						|
_PROTOTYPE(void pushio, (struct ioarg *argp, int (*fn)()));
 | 
						|
_PROTOTYPE(static int xxchar, (struct ioarg *ap ));
 | 
						|
_PROTOTYPE(void tempname, (char *tname ));
 | 
						|
 | 
						|
int
 | 
						|
getc(ec)
 | 
						|
register int ec;
 | 
						|
{
 | 
						|
	register int c;
 | 
						|
 | 
						|
	if(e.linep > elinep) {
 | 
						|
		while((c=readc()) != '\n' && c)
 | 
						|
			;
 | 
						|
		err("input line too long");
 | 
						|
		gflg++;
 | 
						|
		return(c);
 | 
						|
	}
 | 
						|
	c = readc();
 | 
						|
 	if (ec != '\'' && e.iop->task != XGRAVE) {
 | 
						|
		if(c == '\\') {
 | 
						|
			c = readc();
 | 
						|
			if (c == '\n' && ec != '\"')
 | 
						|
				return(getc(ec));
 | 
						|
			c |= QUOTE;
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return(c);
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
unget(c)
 | 
						|
int c;
 | 
						|
{
 | 
						|
	if (e.iop >= e.iobase)
 | 
						|
		e.iop->peekc = c;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
eofc()
 | 
						|
 | 
						|
{
 | 
						|
  return e.iop < e.iobase || (e.iop->peekc == 0 && e.iop->prev == 0);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
readc()
 | 
						|
{
 | 
						|
	register c;
 | 
						|
 | 
						|
	for (; e.iop >= e.iobase; e.iop--)
 | 
						|
		if ((c = e.iop->peekc) != '\0') {
 | 
						|
			e.iop->peekc = 0;
 | 
						|
			return(c);
 | 
						|
		}
 | 
						|
		else {
 | 
						|
		    if (e.iop->prev != 0) {
 | 
						|
		        if ((c = (*e.iop->iofn)(e.iop->argp, e.iop)) != '\0') {
 | 
						|
			        if (c == -1) {
 | 
						|
				        e.iop++;
 | 
						|
				        continue;
 | 
						|
			        }
 | 
						|
			        if (e.iop == iostack)
 | 
						|
				        ioecho(c);
 | 
						|
			        return(e.iop->prev = c);
 | 
						|
		        }
 | 
						|
		        else if (e.iop->task == XIO && e.iop->prev != '\n') {
 | 
						|
			        e.iop->prev = 0;
 | 
						|
				if (e.iop == iostack)
 | 
						|
					ioecho('\n');
 | 
						|
			        return '\n';
 | 
						|
		        }
 | 
						|
		    }
 | 
						|
		    if (e.iop->task == XIO) {
 | 
						|
			if (multiline)
 | 
						|
			    return e.iop->prev = 0;
 | 
						|
			if (talking && e.iop == iostack+1)
 | 
						|
			    prs(prompt->value);
 | 
						|
		    }
 | 
						|
		}
 | 
						|
	if (e.iop >= iostack)
 | 
						|
		return(0);
 | 
						|
	leave();
 | 
						|
	/* NOTREACHED */
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
ioecho(c)
 | 
						|
char c;
 | 
						|
{
 | 
						|
	if (flag['v'])
 | 
						|
		write(2, &c, sizeof c);
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
pushio(argp, fn)
 | 
						|
struct ioarg *argp;
 | 
						|
int (*fn)();
 | 
						|
{
 | 
						|
	if (++e.iop >= &iostack[NPUSH]) {
 | 
						|
		e.iop--;
 | 
						|
		err("Shell input nested too deeply");
 | 
						|
		gflg++;
 | 
						|
		return;
 | 
						|
	}
 | 
						|
	e.iop->iofn = fn;
 | 
						|
 | 
						|
	if (argp->afid != AFID_NOBUF)
 | 
						|
	  e.iop->argp = argp;
 | 
						|
	else {
 | 
						|
	  e.iop->argp  = ioargstack + (e.iop - iostack);
 | 
						|
	  *e.iop->argp = *argp;
 | 
						|
	  e.iop->argp->afbuf = e.iop == &iostack[0] ? &mainbuf : &sharedbuf;
 | 
						|
	  if (isatty(e.iop->argp->afile) == 0 &&
 | 
						|
	      (e.iop == &iostack[0] ||
 | 
						|
	       lseek(e.iop->argp->afile, 0L, 1) != -1)) {
 | 
						|
	    if (++bufid == AFID_NOBUF)
 | 
						|
	      bufid = AFID_ID;
 | 
						|
	    e.iop->argp->afid  = bufid;
 | 
						|
	  }
 | 
						|
	}
 | 
						|
 | 
						|
	e.iop->prev  = ~'\n';
 | 
						|
	e.iop->peekc = 0;
 | 
						|
	e.iop->xchar = 0;
 | 
						|
	e.iop->nlcount = 0;
 | 
						|
	if (fn == filechar || fn == linechar)
 | 
						|
		e.iop->task = XIO;
 | 
						|
	else if (fn == gravechar || fn == qgravechar)
 | 
						|
		e.iop->task = XGRAVE;
 | 
						|
	else
 | 
						|
		e.iop->task = XOTHER;
 | 
						|
}
 | 
						|
 | 
						|
struct io *
 | 
						|
setbase(ip)
 | 
						|
struct io *ip;
 | 
						|
{
 | 
						|
	register struct io *xp;
 | 
						|
 | 
						|
	xp = e.iobase;
 | 
						|
	e.iobase = ip;
 | 
						|
	return(xp);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Input generating functions
 | 
						|
 */
 | 
						|
 | 
						|
/*
 | 
						|
 * Produce the characters of a string, then a newline, then EOF.
 | 
						|
 */
 | 
						|
int
 | 
						|
nlchar(ap)
 | 
						|
register struct ioarg *ap;
 | 
						|
{
 | 
						|
	register int c;
 | 
						|
 | 
						|
	if (ap->aword == NULL)
 | 
						|
		return(0);
 | 
						|
	if ((c = *ap->aword++) == 0) {
 | 
						|
		ap->aword = NULL;
 | 
						|
		return('\n');
 | 
						|
	}
 | 
						|
	return(c);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Given a list of words, produce the characters
 | 
						|
 * in them, with a space after each word.
 | 
						|
 */
 | 
						|
int
 | 
						|
wdchar(ap)
 | 
						|
register struct ioarg *ap;
 | 
						|
{
 | 
						|
	register char c;
 | 
						|
	register char **wl;
 | 
						|
 | 
						|
	if ((wl = ap->awordlist) == NULL)
 | 
						|
		return(0);
 | 
						|
	if (*wl != NULL) {
 | 
						|
		if ((c = *(*wl)++) != 0)
 | 
						|
			return(c & 0177);
 | 
						|
		ap->awordlist++;
 | 
						|
		return(' ');
 | 
						|
	}
 | 
						|
	ap->awordlist = NULL;
 | 
						|
	return('\n');
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Return the characters of a list of words,
 | 
						|
 * producing a space between them.
 | 
						|
 */
 | 
						|
int
 | 
						|
dolchar(ap)
 | 
						|
register struct ioarg *ap;
 | 
						|
{
 | 
						|
	register char *wp;
 | 
						|
 | 
						|
	if ((wp = *ap->awordlist++) != NULL) {
 | 
						|
		PUSHIO(aword, wp, *ap->awordlist == NULL? strchar: xxchar);
 | 
						|
		return(-1);
 | 
						|
	}
 | 
						|
	return(0);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
xxchar(ap)
 | 
						|
register struct ioarg *ap;
 | 
						|
{
 | 
						|
	register int c;
 | 
						|
 | 
						|
	if (ap->aword == NULL)
 | 
						|
		return(0);
 | 
						|
	if ((c = *ap->aword++) == '\0') {
 | 
						|
		ap->aword = NULL;
 | 
						|
		return(' ');
 | 
						|
	}
 | 
						|
	return(c);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Produce the characters from a single word (string).
 | 
						|
 */
 | 
						|
int
 | 
						|
strchar(ap)
 | 
						|
register struct ioarg *ap;
 | 
						|
{
 | 
						|
	register int c;
 | 
						|
 | 
						|
	if (ap->aword == NULL || (c = *ap->aword++) == 0)
 | 
						|
		return(0);
 | 
						|
	return(c);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Produce quoted characters from a single word (string).
 | 
						|
 */
 | 
						|
int
 | 
						|
qstrchar(ap)
 | 
						|
register struct ioarg *ap;
 | 
						|
{
 | 
						|
	register int c;
 | 
						|
 | 
						|
	if (ap->aword == NULL || (c = *ap->aword++) == 0)
 | 
						|
		return(0);
 | 
						|
	return(c|QUOTE);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Return the characters from a file.
 | 
						|
 */
 | 
						|
int
 | 
						|
filechar(ap)
 | 
						|
register struct ioarg *ap;
 | 
						|
{
 | 
						|
	register int i;
 | 
						|
	char c;
 | 
						|
	struct iobuf *bp = ap->afbuf;
 | 
						|
 | 
						|
	if (ap->afid != AFID_NOBUF) {
 | 
						|
	  if ((i = ap->afid != bp->id) || bp->bufp == bp->ebufp) {
 | 
						|
	    if (i)
 | 
						|
	      lseek(ap->afile, ap->afpos, 0);
 | 
						|
	    do {
 | 
						|
	      i = read(ap->afile, bp->buf, sizeof(bp->buf));
 | 
						|
	    } while (i < 0 && errno == EINTR);
 | 
						|
	    if (i <= 0) {
 | 
						|
	      closef(ap->afile);
 | 
						|
	      return 0;
 | 
						|
	    }
 | 
						|
	    bp->id = ap->afid;
 | 
						|
	    bp->ebufp = (bp->bufp  = bp->buf) + i;
 | 
						|
	  }
 | 
						|
	  ap->afpos++;
 | 
						|
	  return *bp->bufp++ & 0177;
 | 
						|
	}
 | 
						|
 | 
						|
	do {
 | 
						|
		i = read(ap->afile, &c, sizeof(c));
 | 
						|
	} while (i < 0 && errno == EINTR);
 | 
						|
	return(i == sizeof(c)? c&0177: (closef(ap->afile), 0));
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Return the characters from a here temp file.
 | 
						|
 */
 | 
						|
int
 | 
						|
herechar(ap)
 | 
						|
register struct ioarg *ap;
 | 
						|
{
 | 
						|
	char c;
 | 
						|
 | 
						|
 | 
						|
	if (read(ap->afile, &c, sizeof(c)) != sizeof(c)) {
 | 
						|
		close(ap->afile);
 | 
						|
		c = 0;
 | 
						|
	}
 | 
						|
	return (c);
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Return the characters produced by a process (`...`).
 | 
						|
 * Quote them if required, and remove any trailing newline characters.
 | 
						|
 */
 | 
						|
int
 | 
						|
gravechar(ap, iop)
 | 
						|
struct ioarg *ap;
 | 
						|
struct io *iop;
 | 
						|
{
 | 
						|
	register int c;
 | 
						|
 | 
						|
	if ((c = qgravechar(ap, iop)&~QUOTE) == '\n')
 | 
						|
		c = ' ';
 | 
						|
	return(c);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
qgravechar(ap, iop)
 | 
						|
register struct ioarg *ap;
 | 
						|
struct io *iop;
 | 
						|
{
 | 
						|
	register int c;
 | 
						|
 | 
						|
	if (iop->xchar) {
 | 
						|
		if (iop->nlcount) {
 | 
						|
			iop->nlcount--;
 | 
						|
			return('\n'|QUOTE);
 | 
						|
		}
 | 
						|
		c = iop->xchar;
 | 
						|
		iop->xchar = 0;
 | 
						|
	} else if ((c = filechar(ap)) == '\n') {
 | 
						|
		iop->nlcount = 1;
 | 
						|
		while ((c = filechar(ap)) == '\n')
 | 
						|
			iop->nlcount++;
 | 
						|
		iop->xchar = c;
 | 
						|
		if (c == 0)
 | 
						|
			return(c);
 | 
						|
		iop->nlcount--;
 | 
						|
		c = '\n';
 | 
						|
	}
 | 
						|
	return(c!=0? c|QUOTE: 0);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Return a single command (usually the first line) from a file.
 | 
						|
 */
 | 
						|
int
 | 
						|
linechar(ap)
 | 
						|
register struct ioarg *ap;
 | 
						|
{
 | 
						|
	register int c;
 | 
						|
 | 
						|
	if ((c = filechar(ap)) == '\n') {
 | 
						|
		if (!multiline) {
 | 
						|
			closef(ap->afile);
 | 
						|
			ap->afile = -1;	/* illegal value */
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return(c);
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
prs(s)
 | 
						|
register char *s;
 | 
						|
{
 | 
						|
	if (*s)
 | 
						|
		write(2, s, strlen(s));
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
putc(c)
 | 
						|
char c;
 | 
						|
{
 | 
						|
	write(2, &c, sizeof c);
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
prn(u)
 | 
						|
unsigned u;
 | 
						|
{
 | 
						|
	prs(itoa(u, 0));
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
closef(i)
 | 
						|
register int i;
 | 
						|
{
 | 
						|
	if (i > 2)
 | 
						|
		close(i);
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
closeall()
 | 
						|
{
 | 
						|
	register u;
 | 
						|
 | 
						|
	for (u=NUFILE; u<NOFILE;)
 | 
						|
		close(u++);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * remap fd into Shell's fd space
 | 
						|
 */
 | 
						|
int
 | 
						|
remap(fd)
 | 
						|
register int fd;
 | 
						|
{
 | 
						|
	register int i;
 | 
						|
	int map[NOFILE];
 | 
						|
 | 
						|
	if (fd < e.iofd) {
 | 
						|
		for (i=0; i<NOFILE; i++)
 | 
						|
			map[i] = 0;
 | 
						|
		do {
 | 
						|
			map[fd] = 1;
 | 
						|
			fd = dup(fd);
 | 
						|
		} while (fd >= 0 && fd < e.iofd);
 | 
						|
		for (i=0; i<NOFILE; i++)
 | 
						|
			if (map[i])
 | 
						|
				close(i);
 | 
						|
		if (fd < 0)
 | 
						|
			err("too many files open in shell");
 | 
						|
	}
 | 
						|
	return(fd);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
openpipe(pv)
 | 
						|
register int *pv;
 | 
						|
{
 | 
						|
	register int i;
 | 
						|
 | 
						|
	if ((i = pipe(pv)) < 0)
 | 
						|
		err("can't create pipe - try again");
 | 
						|
	return(i);
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
closepipe(pv)
 | 
						|
register int *pv;
 | 
						|
{
 | 
						|
	if (pv != NULL) {
 | 
						|
		close(*pv++);
 | 
						|
		close(*pv);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
/* -------- here.c -------- */
 | 
						|
/* #include "sh.h" */
 | 
						|
 | 
						|
/*
 | 
						|
 * here documents
 | 
						|
 */
 | 
						|
 | 
						|
struct	here {
 | 
						|
	char	*h_tag;
 | 
						|
	int	h_dosub;
 | 
						|
	struct	ioword *h_iop;
 | 
						|
	struct	here	*h_next;
 | 
						|
};
 | 
						|
 | 
						|
static	struct here *inhere;		/* list of hear docs while parsing */
 | 
						|
static	struct here *acthere;		/* list of active here documents */
 | 
						|
 | 
						|
void
 | 
						|
inithere()
 | 
						|
{
 | 
						|
	inhere=acthere=(struct here*)0;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
markhere(s, iop)
 | 
						|
register char *s;
 | 
						|
struct ioword *iop;
 | 
						|
{
 | 
						|
	register struct here *h, *lh;
 | 
						|
 | 
						|
	h = (struct here *) space(sizeof(struct here));
 | 
						|
	if (h == 0)
 | 
						|
		return;
 | 
						|
	h->h_tag = evalstr(s, DOSUB);
 | 
						|
	if (h->h_tag == 0)
 | 
						|
		return;
 | 
						|
	h->h_iop = iop;
 | 
						|
	iop->io_name = 0;
 | 
						|
	h->h_next = NULL;
 | 
						|
	if (inhere == 0)
 | 
						|
		inhere = h;
 | 
						|
	else
 | 
						|
		for (lh = inhere; lh!=NULL; lh = lh->h_next)
 | 
						|
			if (lh->h_next == 0) {
 | 
						|
				lh->h_next = h;
 | 
						|
				break;
 | 
						|
			}
 | 
						|
	iop->io_flag |= IOHERE|IOXHERE;
 | 
						|
	for (s = h->h_tag; *s; s++)
 | 
						|
		if (*s & QUOTE) {
 | 
						|
			iop->io_flag &= ~ IOXHERE;
 | 
						|
			*s &= ~ QUOTE;
 | 
						|
		}
 | 
						|
	h->h_dosub = iop->io_flag & IOXHERE;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
gethere()
 | 
						|
{
 | 
						|
	register struct here *h, *hp;
 | 
						|
 | 
						|
	/* Scan here files first leaving inhere list in place */
 | 
						|
	for (hp = h = inhere; h != NULL; hp = h, h = h->h_next)
 | 
						|
	  readhere(&h->h_iop->io_name, h->h_tag, h->h_dosub? 0: '\'');
 | 
						|
 | 
						|
	/* Make inhere list active - keep list intact for scraphere */
 | 
						|
	if (hp != NULL) {
 | 
						|
	  hp->h_next = acthere;
 | 
						|
	  acthere    = inhere;
 | 
						|
	  inhere     = NULL;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
readhere(name, s, ec)
 | 
						|
char **name;
 | 
						|
register char *s;
 | 
						|
int ec;
 | 
						|
{
 | 
						|
	int tf;
 | 
						|
	char tname[30];
 | 
						|
	register c;
 | 
						|
	jmp_buf ev;
 | 
						|
	char line [LINELIM+1];
 | 
						|
	char *next;
 | 
						|
 | 
						|
	tempname(tname);
 | 
						|
	*name = strsave(tname, areanum);
 | 
						|
	tf = creat(tname, 0600);
 | 
						|
	if (tf < 0)
 | 
						|
		return;
 | 
						|
	if (newenv(setjmp(errpt = ev)) != 0)
 | 
						|
		unlink(tname);
 | 
						|
	else {
 | 
						|
		pushio(e.iop->argp, e.iop->iofn);
 | 
						|
		e.iobase = e.iop;
 | 
						|
		for (;;) {
 | 
						|
			if (talking && e.iop <= iostack)
 | 
						|
				prs(cprompt->value);
 | 
						|
			next = line;
 | 
						|
			while ((c = readc()) != '\n' && c) {
 | 
						|
				if (next >= &line[LINELIM]) {
 | 
						|
					c = 0;
 | 
						|
					break;
 | 
						|
				}
 | 
						|
				*next++ = c;
 | 
						|
			}
 | 
						|
			*next = 0;
 | 
						|
			if (strcmp(s, line) == 0 || c == 0)
 | 
						|
				break;
 | 
						|
			*next++ = '\n';
 | 
						|
			write (tf, line, (int)(next-line));
 | 
						|
		}
 | 
						|
		if (c == 0) {
 | 
						|
			prs("here document `"); prs(s); err("' unclosed");
 | 
						|
		}
 | 
						|
		quitenv();
 | 
						|
	}
 | 
						|
	close(tf);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * open here temp file.
 | 
						|
 * if unquoted here, expand here temp file into second temp file.
 | 
						|
 */
 | 
						|
int
 | 
						|
herein(hname, xdoll)
 | 
						|
char *hname;
 | 
						|
int xdoll;
 | 
						|
{
 | 
						|
	register hf, tf;
 | 
						|
 | 
						|
	if (hname == 0)
 | 
						|
		return(-1);
 | 
						|
	hf = open(hname, 0);
 | 
						|
	if (hf < 0)
 | 
						|
		return (-1);
 | 
						|
	if (xdoll) {
 | 
						|
		char c;
 | 
						|
		char tname[30];
 | 
						|
		jmp_buf ev;
 | 
						|
 | 
						|
		tempname(tname);
 | 
						|
		if ((tf = creat(tname, 0600)) < 0)
 | 
						|
			return (-1);
 | 
						|
		if (newenv(setjmp(errpt = ev)) == 0) {
 | 
						|
			PUSHIO(afile, hf, herechar);
 | 
						|
			setbase(e.iop);
 | 
						|
			while ((c = subgetc(0, 0)) != 0) {
 | 
						|
				char c1 = c&~QUOTE;
 | 
						|
 | 
						|
				if (c"E && !any(c1,"`$\\"))
 | 
						|
					write(tf,"\\",1);
 | 
						|
				write(tf, &c1, 1);
 | 
						|
			}
 | 
						|
			quitenv();
 | 
						|
		} else
 | 
						|
			unlink(tname);
 | 
						|
		close(tf);
 | 
						|
		tf = open(tname, 0);
 | 
						|
		unlink(tname);
 | 
						|
		return (tf);
 | 
						|
	} else
 | 
						|
		return (hf);
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
scraphere()
 | 
						|
{
 | 
						|
	register struct here *h;
 | 
						|
 | 
						|
	for (h = inhere; h != NULL; h = h->h_next) {
 | 
						|
		if (h->h_iop && h->h_iop->io_name)
 | 
						|
		  unlink(h->h_iop->io_name);
 | 
						|
	}
 | 
						|
	inhere = NULL;
 | 
						|
}
 | 
						|
 | 
						|
/* unlink here temp files before a freearea(area) */
 | 
						|
void
 | 
						|
freehere(area)
 | 
						|
int area;
 | 
						|
{
 | 
						|
	register struct here *h, *hl;
 | 
						|
 | 
						|
	hl = NULL;
 | 
						|
	for (h = acthere; h != NULL; h = h->h_next)
 | 
						|
		if (getarea((char *) h) >= area) {
 | 
						|
			if (h->h_iop->io_name != NULL)
 | 
						|
				unlink(h->h_iop->io_name);
 | 
						|
			if (hl == NULL)
 | 
						|
				acthere = h->h_next;
 | 
						|
			else
 | 
						|
				hl->h_next = h->h_next;
 | 
						|
		} else
 | 
						|
			hl = h;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
tempname(tname)
 | 
						|
char *tname;
 | 
						|
{
 | 
						|
	static int inc;
 | 
						|
	register char *cp, *lp;
 | 
						|
 | 
						|
	for (cp = tname, lp = "/tmp/shtm"; (*cp = *lp++) != '\0'; cp++)
 | 
						|
		;
 | 
						|
	lp = putn(getpid()*1000 + inc++);
 | 
						|
	for (; (*cp = *lp++) != '\0'; cp++)
 | 
						|
		;
 | 
						|
}
 |