]> git.lizzy.rs Git - plan9front.git/blob - sys/src/libstdio/_IO_putc.c
vmx: use _actual_ system kbmap
[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                 if(_IO_setvbuf(f)!=0)
22                         return EOF;
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                                 char *t = realloc(f->buf, f->bufl+BUFSIZ);
44                                 if(t==NULL){
45                                         f->state=ERR;
46                                         return EOF;
47                                 }
48                                 f->buf=t;
49                                 f->wp=t+f->bufl;
50                                 f->bufl+=BUFSIZ;
51                                 f->rp=t+f->bufl;
52                         }else{
53                                 f->state=ERR;
54                                 return EOF;
55                         }
56                 }
57                 *f->wp++=c;
58         }
59         else if(f->flags&LINEBUF){
60                 if(f->lp==f->rp){
61                         cnt=f->lp-f->buf;
62                         if(f->flags&APPEND) seek(f->fd, 0L, 2);
63                         if(cnt!=0 && write(f->fd, f->buf, cnt)!=cnt){
64                                 f->state=ERR;
65                                 return EOF;
66                         }
67                         f->lp=f->buf;
68                 }
69                 *f->lp++=c;
70                 if(c=='\n'){
71                         cnt=f->lp-f->buf;
72                         if(f->flags&APPEND) seek(f->fd, 0L, 2);
73                         if(cnt!=0 && write(f->fd, f->buf, cnt)!=cnt){
74                                 f->state=ERR;
75                                 return EOF;
76                         }
77                         f->lp=f->buf;
78                 }
79         }
80         else if(f->buf==f->unbuf){
81                 f->unbuf[0]=c;
82                 if(f->flags&APPEND) seek(f->fd, 0L, 2);
83                 if(write(f->fd, f->buf, 1)!=1){
84                         f->state=ERR;
85                         return EOF;
86                 }
87         }
88         else{
89                 if(f->wp==f->rp){
90                         cnt=f->wp-f->buf;
91                         if(f->flags&APPEND) seek(f->fd, 0L, 2);
92                         if(cnt!=0 && write(f->fd, f->buf, cnt)!=cnt){
93                                 f->state=ERR;
94                                 return EOF;
95                         }
96                         f->wp=f->buf;
97                         f->rp=f->buf+f->bufl;
98                 }
99                 *f->wp++=c;
100         }
101         f->state=WR;
102         /*
103          * Make sure EOF looks different from putc(-1)
104          * Should be able to cast to unsigned char, but
105          * there's a vc bug preventing that from working
106          */
107         return c&0xff;
108 }