xref: /csrg-svn/local/toolchest/ksh/sh/io.c (revision 35146)
1*35146Smarc /* @(#)io.c	1.1 */
2*35146Smarc /*
3*35146Smarc  * UNIX shell
4*35146Smarc  *
5*35146Smarc  * S. R. Bourne
6*35146Smarc  * Rewritten by David Korn
7*35146Smarc  * AT&T Bell Laboratories
8*35146Smarc  *
9*35146Smarc  */
10*35146Smarc 
11*35146Smarc #include	<errno.h>
12*35146Smarc #if BSD
13*35146Smarc #include	<sys/types.h>
14*35146Smarc #include	<sys/stat.h>
15*35146Smarc #include	<sys/ioctl.h>
16*35146Smarc # ifdef BSD_4_2
17*35146Smarc # include	<fcntl.h>
18*35146Smarc # endif	/* BSD_4_2 */
19*35146Smarc # define CAST	(char*)
20*35146Smarc #else
21*35146Smarc # ifdef VENIX
22*35146Smarc # include	<sys/types.h>
23*35146Smarc # include	<sys/stat.h>
24*35146Smarc # define CAST	(char*)
25*35146Smarc # else
26*35146Smarc # include	<fcntl.h>
27*35146Smarc # define CAST	(unsigned char*)
28*35146Smarc # endif	/* VENIX */
29*35146Smarc #endif	/* BSD */
30*35146Smarc #include	"defs.h"
31*35146Smarc #include	"flags.h"
32*35146Smarc #include	"sym.h"
33*35146Smarc #include	"io.h"
34*35146Smarc #include	"shtype.h"
35*35146Smarc #ifndef F_DUPFD
36*35146Smarc #define	F_DUPFD	0
37*35146Smarc #define NO_FCNTL 1
38*35146Smarc #endif	/* F_DUPFD */
39*35146Smarc 
40*35146Smarc /* This module defines the following routines */
41*35146Smarc FILE *fdopen();
42*35146Smarc FILE *create();
43*35146Smarc FILE *chkrdwr();
44*35146Smarc int	ispipe();
45*35146Smarc void	sync_io();
46*35146Smarc void	settemp();
47*35146Smarc void	swap_iodoc_nm();
48*35146Smarc void	initf();
49*35146Smarc void	restore();
50*35146Smarc int	estabf();
51*35146Smarc void	chkpipe();
52*35146Smarc 
53*35146Smarc /* This module references the following externals */
54*35146Smarc extern STKPTR locstak(),cpystak();
55*35146Smarc extern void chkpr();
56*35146Smarc extern void failed();
57*35146Smarc extern void free();
58*35146Smarc extern char *heap();
59*35146Smarc extern char *itos();
60*35146Smarc extern long lseek();
61*35146Smarc extern char *movstr();
62*35146Smarc extern void p_flush();
63*35146Smarc extern char *strrchr();
64*35146Smarc 
65*35146Smarc 
66*35146Smarc static int qtrim();
67*35146Smarc static int serial;
68*35146Smarc static char *temp_suffix;
69*35146Smarc static struct filesave fdmap[MAXFILES];
70*35146Smarc 
71*35146Smarc 
72*35146Smarc /* ======== input output and file copying ======== */
73*35146Smarc 
74*35146Smarc /*
75*35146Smarc  * initialize temp file names
76*35146Smarc  */
settemp(pid)77*35146Smarc void settemp(pid)
78*35146Smarc char *pid;
79*35146Smarc {
80*35146Smarc 	register char *sp = movstr(pid,tmpout+7);
81*35146Smarc 	*sp++ = '.';
82*35146Smarc 	temp_suffix = sp;
83*35146Smarc 	serial = 0;
84*35146Smarc 	states &= ~NO_TMP;
85*35146Smarc }
86*35146Smarc 
87*35146Smarc /*
88*35146Smarc  * set up a fileblk associated with the stream fd
89*35146Smarc  */
90*35146Smarc 
initf(fd)91*35146Smarc void	initf(fd)
92*35146Smarc FILE	*fd;
93*35146Smarc {
94*35146Smarc 	register SHFILE f=standin;
95*35146Smarc 	f->fdes=fd;
96*35146Smarc 	f->feval=0;
97*35146Smarc 	f->flin=1;
98*35146Smarc }
99*35146Smarc 
100*35146Smarc /*
101*35146Smarc  * set up an I/O stream that will cause reading from a string
102*35146Smarc  */
103*35146Smarc 
estabf(s,fd)104*35146Smarc int	estabf(s,fd)
105*35146Smarc register FILE *fd;
106*35146Smarc register char *s;
107*35146Smarc {
108*35146Smarc 	register SHFILE f;
109*35146Smarc 	(f=standin)->fdes = fd;
110*35146Smarc 	fd->_flag = _IOREAD;
111*35146Smarc 	fd->_base = fd->_ptr = CAST s;
112*35146Smarc 	fd->_file = F_STRING;
113*35146Smarc 	fd->_cnt = F_INFINITE;
114*35146Smarc 	f->flin = 1;
115*35146Smarc 	fd->_flag|=(s==0?_IOEOF:0);
116*35146Smarc 	return(feof(fd));
117*35146Smarc }
118*35146Smarc 
push(af)119*35146Smarc push(af)
120*35146Smarc SHFILE af;
121*35146Smarc {
122*35146Smarc 	register SHFILE f;
123*35146Smarc 	(f=af)->fstak=standin;
124*35146Smarc 	f->feval=0;
125*35146Smarc 	standin=f;
126*35146Smarc }
127*35146Smarc 
pop(flag)128*35146Smarc pop(flag)
129*35146Smarc register int flag;
130*35146Smarc {
131*35146Smarc 	register SHFILE f;
132*35146Smarc 	register FILE *fd;
133*35146Smarc 	register int fno;
134*35146Smarc 	if((f=standin)->fstak)
135*35146Smarc 	{
136*35146Smarc 		fd = f->fdes;
137*35146Smarc 		fno = fileno(fd);
138*35146Smarc 		if(flag==0 && fno>0 && fno!=F_STRING && fno!=INIO && fd!=cpipe[INPIPE])
139*35146Smarc 			closefd(fd);
140*35146Smarc 		standin=f->fstak;
141*35146Smarc 		return(1);
142*35146Smarc 	}
143*35146Smarc 	return(0);
144*35146Smarc }
145*35146Smarc 
146*35146Smarc /*
147*35146Smarc  * sync_io - flushes output buffer and positions stdin if necessary
148*35146Smarc  */
149*35146Smarc 
sync_io()150*35146Smarc void sync_io()
151*35146Smarc {
152*35146Smarc 	register FILE *fp = stdin;
153*35146Smarc 	p_flush();
154*35146Smarc 	/* position back the read-ahead characters */
155*35146Smarc 	if(fp->_cnt)
156*35146Smarc 	{
157*35146Smarc 		lseek(fileno(fp),-((long)(fp->_cnt)),1);
158*35146Smarc 		setbuf(fp,(char*)fp->_base);
159*35146Smarc 	}
160*35146Smarc }
161*35146Smarc 
162*35146Smarc 
163*35146Smarc /*
164*35146Smarc  * This non-standard version of fdopen makes stream numbers
165*35146Smarc  * correspond to file unit numbers
166*35146Smarc  */
167*35146Smarc 
fdopen(fd,mode)168*35146Smarc FILE *fdopen(fd, mode)
169*35146Smarc register int	fd;
170*35146Smarc register char *mode;
171*35146Smarc {
172*35146Smarc 	register FILE *iop;
173*35146Smarc 	if(fd < 0)
174*35146Smarc 		return(NULL);
175*35146Smarc 	iop = file_fd(fd);
176*35146Smarc 	iop->_cnt = 0;
177*35146Smarc 	iop->_file = fd;
178*35146Smarc 	iop->_base = NULL;
179*35146Smarc 	switch(*mode)
180*35146Smarc 	{
181*35146Smarc 
182*35146Smarc 		 case 'r':
183*35146Smarc 			iop->_flag |= _IOREAD;
184*35146Smarc 			break;
185*35146Smarc 		 case 'a':
186*35146Smarc 			lseek(fd, 0L, 2);
187*35146Smarc 			/* No break */
188*35146Smarc 		 case 'w':
189*35146Smarc 			iop->_flag |= _IOWRT;
190*35146Smarc 			break;
191*35146Smarc 		 default:
192*35146Smarc 			return(NULL);
193*35146Smarc 		}
194*35146Smarc 
195*35146Smarc 	if(mode[1] == '+')
196*35146Smarc 	{
197*35146Smarc 		 iop->_flag &= ~(_IOREAD | _IOWRT);
198*35146Smarc 		 iop->_flag |= _IORW;
199*35146Smarc 		}
200*35146Smarc 	return(iop);
201*35146Smarc }
202*35146Smarc 
chkpipe(pv)203*35146Smarc void	chkpipe(pv)
204*35146Smarc FILE	*pv[];
205*35146Smarc {
206*35146Smarc 	int ipv[2];
207*35146Smarc 	if(pipe(ipv)<0 || ipv[INPIPE]<0 || ipv[OTPIPE]<0)
208*35146Smarc 		error(piperr);
209*35146Smarc 	pv[INPIPE] = fdopen(ipv[INPIPE],"r");
210*35146Smarc 	pv[OTPIPE] = fdopen(ipv[OTPIPE],"w");
211*35146Smarc }
212*35146Smarc 
213*35146Smarc /*
214*35146Smarc  * close a pipe
215*35146Smarc  */
216*35146Smarc 
pipe_close(pv)217*35146Smarc void pipe_close(pv)
218*35146Smarc register FILE *pv[];
219*35146Smarc {
220*35146Smarc 	if(pv[INPIPE])
221*35146Smarc 		fclose(pv[INPIPE]);
222*35146Smarc 	if(pv[OTPIPE])
223*35146Smarc 		fclose(pv[OTPIPE]);
224*35146Smarc }
225*35146Smarc 
226*35146Smarc /*
227*35146Smarc  * Open a stream for reading
228*35146Smarc  * On failure, print message.
229*35146Smarc  */
230*35146Smarc 
chkopen(name)231*35146Smarc FILE *chkopen(name)
232*35146Smarc register char *name;
233*35146Smarc {
234*35146Smarc 	register FILE	*fd;
235*35146Smarc 	if((fd=fdopen(open(name,0),"r"))==NULL)
236*35146Smarc 		failed(name,badopen);
237*35146Smarc 	return(fd);
238*35146Smarc }
239*35146Smarc 
240*35146Smarc 
241*35146Smarc /*
242*35146Smarc  * given a file stream f1, move it to a new file stream with file number
243*35146Smarc  * f2.  If f2 is open then it is closed first.
244*35146Smarc  * If the MARK bit not set on f2, then close on exec will be set for f2>2
245*35146Smarc  * The original stream is closed.
246*35146Smarc  * File numbers greater than 2 are marked close on exec if frenumber is
247*35146Smarc  *  invoked by a parent shell.
248*35146Smarc  *  The new file descriptor is returned;
249*35146Smarc  */
250*35146Smarc 
frenumber(f1,f2)251*35146Smarc FILE *frenumber(f1,f2)
252*35146Smarc FILE *f1;
253*35146Smarc register int f2;
254*35146Smarc {
255*35146Smarc 	register FILE *fd;
256*35146Smarc 	register int flag = (f2&MARK);
257*35146Smarc 	register int fs=0;
258*35146Smarc 	register char *type;
259*35146Smarc 	f2 &= ~MARK;
260*35146Smarc 	if(f2>2 && flag==0)
261*35146Smarc 		fs = 1;
262*35146Smarc 	fd = file_fd(f2);
263*35146Smarc 	if(fileno(f1)!=f2)
264*35146Smarc 	{
265*35146Smarc 		int fno;
266*35146Smarc 		if(fs==0)
267*35146Smarc 			fs = fcntl(f2,1,0);
268*35146Smarc 		if(fisopen(fd))
269*35146Smarc 		{
270*35146Smarc 			closefd(fd);
271*35146Smarc 		}
272*35146Smarc 		else
273*35146Smarc 			close(f2);
274*35146Smarc 		fno = fcntl(fileno(f1),0,f2);
275*35146Smarc 		if(fno < 0)
276*35146Smarc 			error(badfile);
277*35146Smarc 		flag = f1->_flag;
278*35146Smarc 		if(flag&_IORW)
279*35146Smarc 			type="w+";
280*35146Smarc 		else
281*35146Smarc 			type = (f1->_flag&_IOREAD?"r":"w");
282*35146Smarc 		fclose(f1);
283*35146Smarc 		fd = fdopen(f2,type);
284*35146Smarc #ifdef apollo
285*35146Smarc 		fd->_file = fno;
286*35146Smarc #endif	/* apollo */
287*35146Smarc 		fd->_flag = flag;
288*35146Smarc 		if(fd==output)
289*35146Smarc 			setbuf(fd,(char*)_sobuf);
290*35146Smarc 		else if(fd==input && (fd->_flag&_IONBF)==0)
291*35146Smarc 			setbuf(fd,(char*)_sibuf);
292*35146Smarc 		else
293*35146Smarc 		{
294*35146Smarc 			fd->_cnt = f1->_cnt;
295*35146Smarc 			fd->_ptr = f1->_ptr;
296*35146Smarc 			fd->_base = f1->_base;
297*35146Smarc 		}
298*35146Smarc 		setbuf(f1,NIL);
299*35146Smarc 		if(f2==0)
300*35146Smarc 			ioset |= 1;
301*35146Smarc 	}
302*35146Smarc 	if(fs==1)
303*35146Smarc #ifdef BSD
304*35146Smarc 		ioctl(f2, FIOCLEX, NULL);
305*35146Smarc #else
306*35146Smarc 		fcntl(f2,2,1);
307*35146Smarc #endif	/* BSD */
308*35146Smarc 	return(fd);
309*35146Smarc }
310*35146Smarc 
tmp_open(fname)311*35146Smarc FILE *tmp_open(fname)
312*35146Smarc register char *fname;
313*35146Smarc {
314*35146Smarc 	register int maxtry = 10;
315*35146Smarc 	register char *tmp_name = tmpout;
316*35146Smarc 	register FILE *fd;
317*35146Smarc 	if(states&NO_TMP)
318*35146Smarc 		settemp(itos(getpid()));
319*35146Smarc 	do
320*35146Smarc 	{
321*35146Smarc 		movstr(itos(++serial),temp_suffix);
322*35146Smarc 	}
323*35146Smarc 	while((fd=create(tmp_name))== NULL && maxtry--);
324*35146Smarc 	if(fname)
325*35146Smarc 	{
326*35146Smarc 		movstr(tmp_name,fname);
327*35146Smarc 		if((fd = chkrdwr(tmp_name,fd))==NULL)
328*35146Smarc 			failed(tmp_name,badcreate);
329*35146Smarc 	}
330*35146Smarc 	return(fd);
331*35146Smarc }
332*35146Smarc 
333*35146Smarc /*
334*35146Smarc  * create the file named s and return an open stream to it
335*35146Smarc  */
336*35146Smarc 
create(s)337*35146Smarc FILE *create(s)
338*35146Smarc char *s;
339*35146Smarc {
340*35146Smarc 	register FILE *fd;
341*35146Smarc 	fd = fdopen(creat(s,0666),"w+");
342*35146Smarc 	return(fd);
343*35146Smarc }
344*35146Smarc 
345*35146Smarc /*
346*35146Smarc  * close file stream and reopen for reading and writing
347*35146Smarc  */
348*35146Smarc 
chkrdwr(name,fd)349*35146Smarc FILE *chkrdwr(name,fd)
350*35146Smarc register char *name;
351*35146Smarc register FILE *fd;
352*35146Smarc {
353*35146Smarc 	if(fd!=NULL)
354*35146Smarc 	{
355*35146Smarc 		fclose(fd);
356*35146Smarc 		fd = fdopen(open(name,2),"w+");
357*35146Smarc 	}
358*35146Smarc 	return(fd);
359*35146Smarc }
360*35146Smarc 
closefd(fd)361*35146Smarc closefd(fd)
362*35146Smarc register FILE *fd;
363*35146Smarc {
364*35146Smarc 
365*35146Smarc 	/* reposition seek pointer if necessary */
366*35146Smarc 	if((fd->_flag&_IOREAD) && fd->_cnt)
367*35146Smarc 		lseek(fileno(fd),-((long)(fd->_cnt)),1);
368*35146Smarc 	free(fd->_base);
369*35146Smarc 	fclose(fd);
370*35146Smarc 	setbuf(fd,NIL);
371*35146Smarc }
372*35146Smarc 
copy(ioparg)373*35146Smarc copy(ioparg)
374*35146Smarc IOPTR	ioparg;
375*35146Smarc {
376*35146Smarc 	register char c = '\n';
377*35146Smarc 	register char *clinep;
378*35146Smarc 	register IOPTR iop;
379*35146Smarc 	register FILE	*fd;
380*35146Smarc 	BOOL 	nosubst;
381*35146Smarc 	char *ends,*cline,obuff[BUFSIZ];
382*35146Smarc 	if(iop=ioparg)
383*35146Smarc 	{
384*35146Smarc 		int stripflg = iop->iofile&IOSTRIP;
385*35146Smarc 		register nlflg = stripflg;
386*35146Smarc 		copy(iop->iolst);
387*35146Smarc 		ends=iop->ioname;
388*35146Smarc 		/* check for and strip quoted characters in ends */
389*35146Smarc 		nosubst = qtrim(ends);
390*35146Smarc 		if(nosubst)
391*35146Smarc 			iop->iofile &= ~IODOC;
392*35146Smarc 		fd = tmp_open(NIL);
393*35146Smarc 		iop->ioname = (char*)cpystak(tmpout);
394*35146Smarc 		setbuf(fd,obuff);
395*35146Smarc 		iop->iolst=iotemp; iotemp=iop;
396*35146Smarc 		cline=(char*)locstak();
397*35146Smarc 		if(stripflg)
398*35146Smarc 			while(*ends=='\t')
399*35146Smarc 				ends++;
400*35146Smarc 		clinep = cline++;
401*35146Smarc 		*cline = 0;
402*35146Smarc 		do
403*35146Smarc 		{
404*35146Smarc 			if(c=='\n')
405*35146Smarc 			{
406*35146Smarc 				*clinep = 0;
407*35146Smarc 				if(eq(ends,cline))
408*35146Smarc 					break;
409*35146Smarc 				chkpr(0);
410*35146Smarc 				*clinep++ = '\n';
411*35146Smarc 				*clinep = 0;
412*35146Smarc 				fputs(cline,fd);
413*35146Smarc 				clinep = cline;
414*35146Smarc 				nlflg = stripflg;
415*35146Smarc 			}
416*35146Smarc 			else if(c=='\t' && nlflg)
417*35146Smarc 				;
418*35146Smarc 			else
419*35146Smarc 			{
420*35146Smarc 				*clinep++ = c;
421*35146Smarc 				nlflg = 0;
422*35146Smarc 			}
423*35146Smarc 		}
424*35146Smarc 		while(c=(nosubst?readc():nextc()));
425*35146Smarc 		closefd(fd);
426*35146Smarc 	}
427*35146Smarc }
428*35146Smarc 
429*35146Smarc /*
430*35146Smarc  * trim quotes and the escapes
431*35146Smarc  * returns non-zero if string is quoted 0 otherwise
432*35146Smarc  */
433*35146Smarc 
qtrim(string)434*35146Smarc static int qtrim(string)
435*35146Smarc char *string;
436*35146Smarc {
437*35146Smarc 	register char *sp = string;
438*35146Smarc 	register char *dp = sp;
439*35146Smarc 	register int c;
440*35146Smarc 	register int quote = 0;
441*35146Smarc 	while(c= *sp++)
442*35146Smarc 	{
443*35146Smarc 		if(c == ESCAPE)
444*35146Smarc 		{
445*35146Smarc 			quote = 1;
446*35146Smarc 			c = *sp++;
447*35146Smarc 		}
448*35146Smarc 		else if(c == '"')
449*35146Smarc 		{
450*35146Smarc 			quote = 1;
451*35146Smarc 			continue;
452*35146Smarc 		}
453*35146Smarc 		*dp++ = c;
454*35146Smarc 	}
455*35146Smarc 	*dp = 0;
456*35146Smarc 	return(quote);
457*35146Smarc }
458*35146Smarc 
459*35146Smarc /*
460*35146Smarc  * short version of fputs
461*35146Smarc  */
462*35146Smarc 
fputs(s,fd)463*35146Smarc int fputs(s,fd)
464*35146Smarc register char *s;
465*35146Smarc register FILE *fd;
466*35146Smarc {
467*35146Smarc 	register char c;
468*35146Smarc 	if(s==NULL || fd==NULL)
469*35146Smarc 		return(EOF);
470*35146Smarc 	while(c = *s++)
471*35146Smarc 		putc(c,fd);
472*35146Smarc 	return(0);
473*35146Smarc }
474*35146Smarc 
475*35146Smarc 
476*35146Smarc /*
477*35146Smarc  * create a link to iodoc for child process to use
478*35146Smarc  */
479*35146Smarc 
link_iodocs(i)480*35146Smarc link_iodocs(i)
481*35146Smarc register struct ionod	*i;
482*35146Smarc {
483*35146Smarc 	while(i)
484*35146Smarc 	{
485*35146Smarc 		/* generate a tempory file name */
486*35146Smarc 		fclose(tmp_open(NIL));
487*35146Smarc 		unlink(tmpout);
488*35146Smarc 		free(i->iolink);
489*35146Smarc 		i->iolink = heap(tmpout);
490*35146Smarc 		link(i->ioname, i->iolink);
491*35146Smarc 		i = i->iolst;
492*35146Smarc 	}
493*35146Smarc }
494*35146Smarc 
495*35146Smarc 
496*35146Smarc /*
497*35146Smarc  * rename the file with the link name of the parent
498*35146Smarc  */
499*35146Smarc 
swap_iodoc_nm(i)500*35146Smarc void	swap_iodoc_nm(i)
501*35146Smarc register struct ionod	*i;
502*35146Smarc {
503*35146Smarc 	while(i)
504*35146Smarc 	{
505*35146Smarc 		free(i->ioname);
506*35146Smarc 		i->ioname = i->iolink;
507*35146Smarc 		i->iolink = 0;
508*35146Smarc 		i = i->iolst;
509*35146Smarc 	}
510*35146Smarc }
511*35146Smarc 
512*35146Smarc 
513*35146Smarc /*
514*35146Smarc  * copy file fd into a save place
515*35146Smarc  */
516*35146Smarc 
savefd(fd,oldtop)517*35146Smarc savefd(fd,oldtop)
518*35146Smarc register int fd;
519*35146Smarc {
520*35146Smarc 	register int	f = topfd;
521*35146Smarc 	register FILE *f1 = file_fd(fd);
522*35146Smarc 	/* see if already saved, only save once */
523*35146Smarc 	while(f > oldtop)
524*35146Smarc 	{
525*35146Smarc 		if(fdmap[--f].org_fd == fd)
526*35146Smarc 			return;
527*35146Smarc 	}
528*35146Smarc 	if(fiswrite(f1))
529*35146Smarc 		fflush(f1);
530*35146Smarc 	else if(f1==stdin)
531*35146Smarc 		sync_io();
532*35146Smarc 	f = fcntl(fd, F_DUPFD, USERIO);
533*35146Smarc 	if(topfd >= MAXFILES)
534*35146Smarc 		error(nomorefiles);
535*35146Smarc 	if(f >= 0)
536*35146Smarc 	{
537*35146Smarc 		*(file_fd(f)) = *f1;
538*35146Smarc 		setbuf(f1,NIL);
539*35146Smarc 	}
540*35146Smarc 	fdmap[topfd].org_fd = fd;
541*35146Smarc 	fdmap[topfd++].dup_fd = f;
542*35146Smarc 	return;
543*35146Smarc }
544*35146Smarc 
545*35146Smarc 
546*35146Smarc /*
547*35146Smarc  *  restore saved file descriptors from <last> on
548*35146Smarc  */
549*35146Smarc 
restore(last)550*35146Smarc void	restore(last)
551*35146Smarc register int	last;
552*35146Smarc {
553*35146Smarc 	register int 	i;
554*35146Smarc 	register int	dupfd;
555*35146Smarc 
556*35146Smarc 	for (i = topfd - 1; i >= last; i--)
557*35146Smarc 	{
558*35146Smarc 		if ((dupfd = fdmap[i].dup_fd) > 0)
559*35146Smarc 		{
560*35146Smarc 			(file_fd(dupfd))->_file = dupfd;
561*35146Smarc 			frenumber(file_fd(dupfd), fdmap[i].org_fd);
562*35146Smarc 		}
563*35146Smarc 		else
564*35146Smarc 			fclose(file_fd(fdmap[i].org_fd));
565*35146Smarc 	}
566*35146Smarc 	topfd = last;
567*35146Smarc }
568*35146Smarc 
569*35146Smarc 
570*35146Smarc /*
571*35146Smarc  * This routine returns 1 if fd corresponds to a pipe, 0 otherwise.
572*35146Smarc  */
573*35146Smarc 
ispipe(fd)574*35146Smarc int ispipe(fd)
575*35146Smarc FILE *fd;
576*35146Smarc {
577*35146Smarc 	register int fno = fileno(fd);
578*35146Smarc 	if(lseek(fno,0L,1)>=0)
579*35146Smarc 		return(0);
580*35146Smarc 	if(errno==ESPIPE)
581*35146Smarc 		return(!isatty(fno));
582*35146Smarc #ifdef BSD
583*35146Smarc 	/* This may be a bug in lseek */
584*35146Smarc 	else if(errno==EINVAL)
585*35146Smarc 		return(1);
586*35146Smarc #endif /* BSD */
587*35146Smarc 	else
588*35146Smarc 		return(0);
589*35146Smarc }
590*35146Smarc 
591*35146Smarc 
592*35146Smarc #if ESH || VSH
593*35146Smarc /*
594*35146Smarc  * Stripped down version of _filbuf from standard I/O library
595*35146Smarc  */
596*35146Smarc 
_filbuf(iop)597*35146Smarc _filbuf(iop)
598*35146Smarc register FILE *iop;
599*35146Smarc {
600*35146Smarc 	register unsigned state = states;
601*35146Smarc 	unsigned char cc;
602*35146Smarc 	register int syncread;
603*35146Smarc 
604*35146Smarc 	if (iop->_flag & _IORW)
605*35146Smarc 		iop->_flag |= _IOREAD;
606*35146Smarc 
607*35146Smarc 	if ((iop->_flag&_IOREAD) == 0)
608*35146Smarc 		return(EOF);
609*35146Smarc 	if(fnobuff(iop))
610*35146Smarc 	{
611*35146Smarc 		/* unbuffered reads needed for pipes */
612*35146Smarc 		p_flush();
613*35146Smarc 		iop->_cnt = read(fileno(iop),(char*)(&cc),1);
614*35146Smarc 		if(iop->_cnt>0)
615*35146Smarc 			{
616*35146Smarc 				iop->_cnt--;
617*35146Smarc 				return(cc);
618*35146Smarc 			}
619*35146Smarc 		goto skip;
620*35146Smarc 	}
621*35146Smarc 	syncread = ((state&PROMPT) && iop==input && (standin->fstak==0||(state&RWAIT)));
622*35146Smarc #ifdef ESH
623*35146Smarc 	if(is_option(EMACS|GMACS) && syncread)
624*35146Smarc 		iop->_cnt = hread(fileno(iop), (char*)iop->_base, BUFSIZ);
625*35146Smarc 	else
626*35146Smarc #endif	/* ESH */
627*35146Smarc #ifdef VSH
628*35146Smarc 	if(is_option(EDITVI) && syncread)
629*35146Smarc 		iop->_cnt = vread(fileno(iop), (unsigned char*)iop->_base, BUFSIZ);
630*35146Smarc 	else
631*35146Smarc #endif	/* VSH */
632*35146Smarc 		{
633*35146Smarc 			/* flush before a read */
634*35146Smarc 			if(syncread)
635*35146Smarc 				p_flush();
636*35146Smarc 			iop->_cnt = read(fileno(iop), (char*)iop->_base, BUFSIZ);
637*35146Smarc 		}
638*35146Smarc 	iop->_ptr = iop->_base;
639*35146Smarc 	skip:
640*35146Smarc 	if (--iop->_cnt < 0)
641*35146Smarc 	{
642*35146Smarc 		if (iop->_cnt == -1)
643*35146Smarc 		{
644*35146Smarc 			iop->_flag |= _IOEOF;
645*35146Smarc 			if (iop->_flag & _IORW)
646*35146Smarc 				iop->_flag &= ~_IOREAD;
647*35146Smarc 		}
648*35146Smarc 		else
649*35146Smarc 			iop->_flag |= _IOERR;
650*35146Smarc 		iop->_cnt = 0;
651*35146Smarc 		return(-1);
652*35146Smarc 	}
653*35146Smarc 	return(*iop->_ptr++&STRIP);
654*35146Smarc }
655*35146Smarc #endif
656*35146Smarc 
657*35146Smarc 
658*35146Smarc #ifdef NO_FCNTL
fcntl(f1,type,arg)659*35146Smarc static int fcntl(f1,type,arg)
660*35146Smarc register int arg;
661*35146Smarc {
662*35146Smarc 	struct stat statbuf;
663*35146Smarc 	if(type==F_DUPFD)
664*35146Smarc 	{
665*35146Smarc 		register int fd;
666*35146Smarc 		/* find first non-open file */
667*35146Smarc 		while(arg < _NFILE &&  (fstat(arg,&statbuf)>=0))
668*35146Smarc 			arg++;
669*35146Smarc 		if(arg >= _NFILE)
670*35146Smarc 			return(-1);
671*35146Smarc 		fd = dup(f1|DUPFLG,arg);
672*35146Smarc 		return(fd);
673*35146Smarc 	   }
674*35146Smarc 	else
675*35146Smarc 		return(0);
676*35146Smarc }
677*35146Smarc #endif	/* NO_FCNTL */
678*35146Smarc 
679*35146Smarc #if u370 || uts
680*35146Smarc 
681*35146Smarc extern int isatty();
682*35146Smarc extern unsigned char _smbuf[][_SBFSIZ];
683*35146Smarc 
setbuf(iop,buf)684*35146Smarc void setbuf(iop, buf)
685*35146Smarc register FILE *iop;
686*35146Smarc char	*buf;
687*35146Smarc {
688*35146Smarc 	register int fno = fileno(iop);  /* file number */
689*35146Smarc 
690*35146Smarc 	if(iop->_base != NULL && iop->_flag & _IOMYBUF)
691*35146Smarc 		free((char*)iop->_base);
692*35146Smarc 	iop->_flag &= ~(_IOMYBUF | _IONBF | _IOLBF);
693*35146Smarc 	if((iop->_base = (unsigned char*)buf) == NULL)
694*35146Smarc 	{
695*35146Smarc 		iop->_flag |= _IONBF; /* file unbuffered except in fastio */
696*35146Smarc 
697*35146Smarc 			_bufend(iop) = (iop->_base = _smbuf[fno]) + _SBFSIZ;
698*35146Smarc 	}
699*35146Smarc 	else
700*35146Smarc 	{  /* regular buffered I/O, standard buffer size */
701*35146Smarc 		_bufend(iop) = iop->_base + BUFSIZ;
702*35146Smarc 		if (isatty(fno))
703*35146Smarc 			iop->_flag |= _IOLBF;
704*35146Smarc 	}
705*35146Smarc 	iop->_ptr = iop->_base;
706*35146Smarc 	iop->_cnt = 0;
707*35146Smarc }
708*35146Smarc #endif	/* u370 */
709*35146Smarc 
710*35146Smarc #ifdef INT16
711*35146Smarc /*
712*35146Smarc  * special version of fread for to save space
713*35146Smarc  * only works if count is 1
714*35146Smarc  */
715*35146Smarc 
fread(ptr,size,count,iop)716*35146Smarc fread(ptr,size,count,iop)
717*35146Smarc register char *ptr;
718*35146Smarc unsigned size,count;
719*35146Smarc register FILE *iop;
720*35146Smarc {
721*35146Smarc 	register int c;
722*35146Smarc 	do
723*35146Smarc 	{
724*35146Smarc 		if((c=getc(iop))>=0)
725*35146Smarc 			*ptr++ = c;
726*35146Smarc 		else
727*35146Smarc 			return(0);
728*35146Smarc 	}
729*35146Smarc 	while(--size);
730*35146Smarc 	return(1);
731*35146Smarc }
732*35146Smarc #endif	/* INT16 */
733*35146Smarc 
734*35146Smarc #ifdef VENIX
getppid()735*35146Smarc int getppid()
736*35146Smarc {
737*35146Smarc 	return(1);
738*35146Smarc }
739*35146Smarc #endif	/* VENIX */
740*35146Smarc 
741*35146Smarc #ifdef _N_STATIC_IOBS
742*35146Smarc /*  ULTRIX doesn't have complete _iob */
743*35146Smarc FILE	_myiob[FCIO+1- _N_STATIC_IOBS];
744*35146Smarc 
file_fd(n)745*35146Smarc FILE	*file_fd(n)
746*35146Smarc {
747*35146Smarc 	if(n < _N_STATIC_IOBS)
748*35146Smarc 		return(&_iob[n]);
749*35146Smarc 	else
750*35146Smarc 		return(&_myiob[n- _N_STATIC_IOBS]);
751*35146Smarc }
752*35146Smarc #endif /* _N_STATIC_IOBS */
753