_IO_putc.c 2.2 KB

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