check for blocks allocated past end of file in indirect blocks
[unix-history] / usr / src / lib / libc / stdio / wbuf.c
CommitLineData
94fe6243 1/* @(#)wbuf.c 4.8 (Berkeley) %G% */
62e7287b 2#include <stdio.h>
f4c06a32
KM
3#include <sys/types.h>
4#include <sys/stat.h>
62e7287b
BJ
5
6char *malloc();
7
8_flsbuf(c, iop)
94fe6243 9unsigned char c;
62e7287b
BJ
10register FILE *iop;
11{
12 register char *base;
13 register n, rn;
14 char c1;
f4c06a32
KM
15 int size;
16 struct stat stbuf;
62e7287b 17
d8af6b8b
MT
18 if (iop->_flag & _IORW) {
19 iop->_flag |= _IOWRT;
ec6ddbc1 20 iop->_flag &= ~(_IOEOF|_IOREAD);
d8af6b8b
MT
21 }
22
62e7287b
BJ
23 if ((iop->_flag&_IOWRT)==0)
24 return(EOF);
25tryagain:
26 if (iop->_flag&_IOLBF) {
27 base = iop->_base;
28 *iop->_ptr++ = c;
f4c06a32 29 if (iop->_ptr >= base+iop->_bufsiz || c == '\n') {
62e7287b
BJ
30 n = write(fileno(iop), base, rn = iop->_ptr - base);
31 iop->_ptr = base;
94fe6243 32 iop->_cnt = 0;
62e7287b
BJ
33 } else
34 rn = n = 0;
62e7287b
BJ
35 } else if (iop->_flag&_IONBF) {
36 c1 = c;
37 rn = 1;
38 n = write(fileno(iop), &c1, rn);
39 iop->_cnt = 0;
40 } else {
41 if ((base=iop->_base)==NULL) {
f4c06a32
KM
42 if (fstat(fileno(iop), &stbuf) < 0 ||
43 stbuf.st_blksize <= NULL)
44 size = BUFSIZ;
45 else
46 size = stbuf.st_blksize;
f4c06a32 47 if ((iop->_base=base=malloc(size)) == NULL) {
62e7287b
BJ
48 iop->_flag |= _IONBF;
49 goto tryagain;
50 }
51 iop->_flag |= _IOMYBUF;
f4c06a32 52 iop->_bufsiz = size;
c528f54e
RC
53 if (iop==stdout && isatty(fileno(stdout))) {
54 iop->_flag |= _IOLBF;
55 iop->_ptr = base;
56 goto tryagain;
57 }
62e7287b
BJ
58 rn = n = 0;
59 } else if ((rn = n = iop->_ptr - base) > 0) {
60 iop->_ptr = base;
61 n = write(fileno(iop), base, n);
62 }
f4c06a32 63 iop->_cnt = iop->_bufsiz-1;
62e7287b
BJ
64 *base++ = c;
65 iop->_ptr = base;
66 }
67 if (rn != n) {
68 iop->_flag |= _IOERR;
69 return(EOF);
70 }
71 return(c);
72}
73
74fflush(iop)
75register struct _iobuf *iop;
76{
77 register char *base;
78 register n;
79
80 if ((iop->_flag&(_IONBF|_IOWRT))==_IOWRT
81 && (base=iop->_base)!=NULL && (n=iop->_ptr-base)>0) {
82 iop->_ptr = base;
f4c06a32 83 iop->_cnt = (iop->_flag&(_IOLBF|_IONBF)) ? 0 : iop->_bufsiz;
62e7287b
BJ
84 if (write(fileno(iop), base, n)!=n) {
85 iop->_flag |= _IOERR;
86 return(EOF);
87 }
88 }
89 return(0);
90}
91
92/*
93 * Flush buffers on exit
94 */
95
96_cleanup()
97{
98 register struct _iobuf *iop;
99 extern struct _iobuf *_lastbuf;
100
101 for (iop = _iob; iop < _lastbuf; iop++)
102 fclose(iop);
103}
104
105fclose(iop)
193b9a78 106 register struct _iobuf *iop;
62e7287b 107{
c13cf752 108 register int r;
62e7287b
BJ
109
110 r = EOF;
d8af6b8b 111 if (iop->_flag&(_IOREAD|_IOWRT|_IORW) && (iop->_flag&_IOSTRG)==0) {
62e7287b
BJ
112 r = fflush(iop);
113 if (close(fileno(iop)) < 0)
114 r = EOF;
115 if (iop->_flag&_IOMYBUF)
116 free(iop->_base);
62e7287b 117 }
62e7287b 118 iop->_cnt = 0;
c13cf752
CC
119 iop->_base = (char *)NULL;
120 iop->_ptr = (char *)NULL;
121 iop->_bufsiz = 0;
122 iop->_flag = 0;
123 iop->_file = 0;
62e7287b
BJ
124 return(r);
125}