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