1 /* 2 * pANS stdio -- _IO_putc, _IO_cleanup 3 */ 4 #include "iolib.h" 5 6 void _IO_cleanup(void){ 7 fflush(NULL); 8 } 9 /* 10 * Look this over for simplification 11 */ 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