_IO_putc.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  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. }