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