xref: /original-bsd/local/toolchest/ksh/sh/stdio.c (revision 5848352c)
1 /*
2 
3  *      Copyright (c) 1984, 1985, 1986 AT&T
4  *      All Rights Reserved
5 
6  *      THIS IS UNPUBLISHED PROPRIETARY SOURCE
7  *      CODE OF AT&T.
8  *      The copyright notice above does not
9  *      evidence any actual or intended
10  *      publication of such source code.
11 
12  */
13 /* @(#)stdio.c	1.1 */
14 /*
15  * adapted for ksh from System V stdio library
16  */
17 #include <stdio.h>
18 
19 #ifndef _IOLBF
20 #define _IOLBF	0400
21 #endif
22 
23 
24 
25 extern long lseek();
26 extern int fflush();
27 
28 #ifdef VENIX
29 #define unsigned
30 #endif	/* VENIX */
31 
32 #ifdef BSD
33 #define unsigned
34 #endif	/* BSD */
35 
36 extern unsigned char _sobuf[];
37 
38 int
39 fseek(iop, offset, ptrname)
40 register FILE *iop;
41 long	offset;
42 register int	ptrname;
43 {
44 	register int c;
45 	long	p;
46 
47 	iop->_flag &= ~_IOEOF;
48 	if(iop->_flag & _IOREAD)
49 	{
50 		if(ptrname < 2 && iop->_base && !(iop->_flag&_IONBF))
51 		{
52 			c = iop->_cnt;
53 			p = offset;
54 			if(ptrname == 0)
55 				p += (long)c-lseek(fileno(iop), 0L, 1);
56 			else
57 				offset -= (long)c;
58 			if(!(iop->_flag&_IORW) && c > 0 && p <= c &&
59 					p >= iop->_base - iop->_ptr)
60 			{
61 				iop->_ptr += (int)p;
62 				iop->_cnt -= (int)p;
63 				return(0);
64 			}
65 		}
66 		if(iop->_flag & _IORW)
67 		{
68 			iop->_ptr = iop->_base;
69 			iop->_flag &= ~_IOREAD;
70 		}
71 		p = lseek(fileno(iop), offset, ptrname);
72 		iop->_cnt = 0;
73 	}
74 	else if(iop->_flag & (_IOWRT | _IORW))
75 	{
76 		(void) fflush(iop);
77 		if(iop->_flag & _IORW)
78 		{
79 			iop->_cnt = 0;
80 			iop->_flag &= ~_IOWRT;
81 			iop->_ptr = iop->_base;
82 		}
83 		p = lseek(fileno(iop), offset, ptrname);
84 	}
85 	return((p == -1)? -1: 0);
86 }
87 
88 void
89 setbuf(iop, buf)
90 register FILE *iop;
91 char	*buf;
92 {
93 	register int fno = fileno(iop);  /* file number */
94 
95 	if(iop->_base != NULL && iop->_flag & _IOMYBUF)
96 		free((char*)iop->_base);
97 	iop->_flag &= ~(_IOMYBUF | _IONBF | _IOLBF);
98 	if((iop->_base = (unsigned char*)buf) == NULL)
99 	{
100 		iop->_flag |= _IONBF;
101 	}
102 	iop->_ptr = iop->_base;
103 	iop->_cnt = 0;
104 }
105 
106 char	*malloc();
107 
108 _flsbuf(c, iop)
109 register FILE *iop;
110 {
111 	register unsigned char *base;
112 	register n, rn;
113 	char c1;
114 
115 	if (iop->_flag & _IORW)
116 	{
117 		iop->_flag |= _IOWRT;
118 		iop->_flag &= ~(_IOEOF|_IOREAD);
119 	}
120 
121 	if ((iop->_flag&_IOWRT)==0)
122 		return(EOF);
123 tryagain:
124 	if (iop->_flag&_IONBF)
125 	{
126 		c1 = c;
127 		rn = 1;
128 		n = write(fileno(iop), &c1, rn);
129 		iop->_cnt = 0;
130 	}
131 	else
132 	{
133 		if ((base=iop->_base)==NULL)
134 		{
135 			if (iop==stdout)
136 			{
137 				if (isatty(fileno(stdout)))
138 					iop->_flag |= _IOLBF;
139 				iop->_base = _sobuf;
140 				iop->_ptr = _sobuf;
141 				goto tryagain;
142 			}
143 			if ((iop->_base=base=(unsigned char*)malloc(BUFSIZ)) == NULL)
144 			{
145 				iop->_flag |= _IONBF;
146 				goto tryagain;
147 			}
148 			iop->_flag |= _IOMYBUF;
149 			rn = n = 0;
150 		}
151 		else if ((rn = n = iop->_ptr - base) > 0)
152 		{
153 			iop->_ptr = base;
154 			n = write(fileno(iop), base, n);
155 		}
156 		iop->_cnt = BUFSIZ-1;
157 		*base++ = c;
158 		iop->_ptr = base;
159 	}
160 	if (rn != n)
161 	{
162 		iop->_flag |= _IOERR;
163 		return(EOF);
164 	}
165 	return(c);
166 }
167 
168 fflush(iop)
169 register FILE *iop;
170 {
171 	register unsigned char *base;
172 	register n;
173 
174 	if ((iop->_flag&(_IONBF|_IOWRT))==_IOWRT
175 	 && (base=iop->_base)!=NULL && (n=iop->_ptr-base)>0)
176 	{
177 		iop->_ptr = base;
178 		iop->_cnt = (iop->_flag&(_IOLBF|_IONBF)) ? 0 : BUFSIZ;
179 		if (write(fileno(iop), base, n)!=n)
180 		{
181 			iop->_flag |= _IOERR;
182 			return(EOF);
183 		}
184 	}
185 	return(0);
186 }
187 
188 /*
189  * Flush buffers on exit
190  */
191 
192 exit(n)
193 {
194 	register FILE *iop;
195 
196 	for (iop = _iob; iop < _iob+_NFILE; iop++)
197 		fclose(iop);
198 	_exit(n);
199 }
200 
201 fclose(iop)
202 	register FILE *iop;
203 {
204 	register int r;
205 
206 	r = EOF;
207 	if (iop->_flag&(_IOREAD|_IOWRT|_IORW))
208 	{
209 		r = fflush(iop);
210 		if (close(fileno(iop)) < 0)
211 			r = EOF;
212 		if (iop->_flag&_IOMYBUF)
213 			free(iop->_base);
214 	}
215 	iop->_cnt = 0;
216 	iop->_base = NULL;
217 	iop->_ptr = NULL;
218 	iop->_flag = 0;
219 	iop->_file = 0;
220 	return(r);
221 }
222 
223 #ifndef INT16
224 /*
225  * special version of fread for to save space
226  * only works if count is 1
227  * code active in io.c when INT16 is on
228  */
229 
230 fread(ptr,size,count,iop)
231 register char *ptr;
232 int size,count;
233 register FILE *iop;
234 {
235 	register int c;
236 	do
237 	{
238 		if((c=getc(iop))>=0)
239 			*ptr++ = c;
240 		else
241 			return(0);
242 	}
243 	while(--size);
244 	return(1);
245 }
246 #endif	/* INT16 */
247 
248 #ifndef VSH
249 #ifndef ESH
250 int	_filbuf(iop)
251 register FILE *iop;
252 {
253 	unsigned char cc;
254 
255 	if (iop->_flag & _IORW)
256 		iop->_flag |= _IOREAD;
257 
258 	if ((iop->_flag&_IOREAD) == 0)
259 		return(EOF);
260 	p_flush();
261 	if((iop->_flag&_IONBF)||iop->_base==NULL)
262 	{
263 		/* unbuffered reads needed for pipes */
264 		iop->_cnt = read(fileno(iop),(char*)(&cc),1);
265 		if(iop->_cnt>0)
266 			{
267 				iop->_cnt--;
268 				return(cc);
269 			}
270 		goto skip;
271 	}
272 	iop->_cnt = read(fileno(iop), (char*)iop->_base, BUFSIZ);
273 	iop->_ptr = iop->_base;
274 skip:
275 	if (--iop->_cnt < 0)
276 	{
277 		if (iop->_cnt == -1)
278 		{
279 			iop->_flag |= _IOEOF;
280 			if (iop->_flag & _IORW)
281 				iop->_flag &= ~_IOREAD;
282 		}
283 		else
284 			iop->_flag |= _IOERR;
285 		iop->_cnt = 0;
286 		return(EOF);
287 	}
288 	return(*iop->_ptr++&0377);
289 }
290 #endif /* ESH */
291 #endif /* VSH */
292