1 /*
2 * pANS stdio -- _IO_putc, _IO_cleanup
3 */
4 #include "iolib.h"
5
_IO_cleanup(void)6 void _IO_cleanup(void){
7 fflush(NULL);
8 }
9 /*
10 * Look this over for simplification
11 */
_IO_putc(int c,FILE * f)12 int _IO_putc(int c, FILE *f){
13 int cnt;
14 static int first=1;
15 switch(f->state){
16 case RD:
17 f->state=ERR;
18 case ERR:
19 case CLOSED:
20 return EOF;
21 case OPEN:
22 _IO_setvbuf(f);
23 /* fall through */
24 case RDWR:
25 case END:
26 f->rp=f->buf+f->bufl;
27 if(f->flags&LINEBUF){
28 f->wp=f->rp;
29 f->lp=f->buf;
30 }
31 else
32 f->wp=f->buf;
33 break;
34 }
35 if(first){
36 atexit(_IO_cleanup);
37 first=0;
38 }
39 if(f->flags&STRING){
40 f->rp=f->buf+f->bufl;
41 if(f->wp==f->rp){
42 if(f->flags&BALLOC)
43 f->buf=realloc(f->buf, f->bufl+BUFSIZ);
44 else{
45 f->state=ERR;
46 return EOF;
47 }
48 if(f->buf==NULL){
49 f->state=ERR;
50 return EOF;
51 }
52 f->rp=f->buf+f->bufl;
53 f->bufl+=BUFSIZ;
54 }
55 *f->wp++=c;
56 }
57 else if(f->flags&LINEBUF){
58 if(f->lp==f->rp){
59 cnt=f->lp-f->buf;
60 if(f->flags&APPEND) lseek(f->fd, 0L, SEEK_END);
61 if(cnt!=0 && write(f->fd, f->buf, cnt)!=cnt){
62 f->state=ERR;
63 return EOF;
64 }
65 f->lp=f->buf;
66 }
67 *f->lp++=c;
68 if(c=='\n'){
69 cnt=f->lp-f->buf;
70 if(f->flags&APPEND) lseek(f->fd, 0L, SEEK_END);
71 if(cnt!=0 && write(f->fd, f->buf, cnt)!=cnt){
72 f->state=ERR;
73 return EOF;
74 }
75 f->lp=f->buf;
76 }
77 }
78 else if(f->buf==f->unbuf){
79 f->unbuf[0]=c;
80 if(f->flags&APPEND) lseek(f->fd, 0L, SEEK_END);
81 if(write(f->fd, f->buf, 1)!=1){
82 f->state=ERR;
83 return EOF;
84 }
85 }
86 else{
87 if(f->wp==f->rp){
88 cnt=f->wp-f->buf;
89 if(f->flags&APPEND) lseek(f->fd, 0L, SEEK_END);
90 if(cnt!=0 && write(f->fd, f->buf, cnt)!=cnt){
91 f->state=ERR;
92 return EOF;
93 }
94 f->wp=f->buf;
95 f->rp=f->buf+f->bufl;
96 }
97 *f->wp++=c;
98 }
99 f->state=WR;
100 /*
101 * Make sure EOF looks different from putc(-1)
102 * Should be able to cast to unsigned char, but
103 * there's a vc bug preventing that from working
104 */
105 return c&0xff;
106 }
107