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