fgetc.c 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. /* Copyright (C) 2004 Manuel Novoa III <mjn3@codepoet.org>
  2. *
  3. * GNU Library General Public License (LGPL) version 2 or later.
  4. *
  5. * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
  6. */
  7. #include "_stdio.h"
  8. #undef fgetc
  9. #undef fgetc_unlocked
  10. #undef getc
  11. #undef getc_unlocked
  12. extern int __fgetc_unlocked(FILE *stream);
  13. #ifdef __DO_UNLOCKED
  14. weak_alias(__fgetc_unlocked,fgetc_unlocked);
  15. weak_alias(__fgetc_unlocked,getc_unlocked);
  16. #ifndef __UCLIBC_HAS_THREADS__
  17. weak_alias(__fgetc_unlocked,fgetc);
  18. weak_alias(__fgetc_unlocked,getc);
  19. #endif
  20. int __fgetc_unlocked(FILE *stream)
  21. {
  22. __STDIO_STREAM_VALIDATE(stream);
  23. /* First the fast path. We're good to go if getc macro enabled. */
  24. if (__STDIO_STREAM_CAN_USE_BUFFER_GET(stream)) {
  25. return __STDIO_STREAM_BUFFER_GET(stream);
  26. }
  27. /* Next quickest... reading and narrow oriented, but macro
  28. * disabled and/or buffer is exhausted. */
  29. if (__STDIO_STREAM_IS_NARROW_READING(stream)
  30. || !__STDIO_STREAM_TRANS_TO_READ(stream, __FLAG_NARROW)
  31. ) {
  32. if (stream->__modeflags & __FLAG_UNGOT) { /* Use ungots first. */
  33. unsigned char uc = stream->__ungot[(stream->__modeflags--) & 1];
  34. stream->__ungot[1] = 0;
  35. __STDIO_STREAM_VALIDATE(stream);
  36. return uc;
  37. }
  38. if (__STDIO_STREAM_BUFFER_RAVAIL(stream)) { /* Have buffered? */
  39. return __STDIO_STREAM_BUFFER_GET(stream);
  40. }
  41. /* Is this a fake stream for *sscanf? */
  42. if (__STDIO_STREAM_IS_FAKE_VSSCANF(stream)) {
  43. __STDIO_STREAM_SET_EOF(stream);
  44. return EOF;
  45. }
  46. /* We need to read from the host environment, so we must
  47. * flush all line buffered streams if the stream is not
  48. * fully buffered. */
  49. if (!__STDIO_STREAM_IS_FBF(stream)) {
  50. __STDIO_FLUSH_LBF_STREAMS;
  51. }
  52. if (__STDIO_STREAM_BUFFER_SIZE(stream)) { /* Do we have a buffer? */
  53. __STDIO_STREAM_DISABLE_GETC(stream);
  54. if(__STDIO_FILL_READ_BUFFER(stream)) { /* Refill succeeded? */
  55. __STDIO_STREAM_ENABLE_GETC(stream); /* FBF or LBF */
  56. return __STDIO_STREAM_BUFFER_GET(stream);
  57. }
  58. } else {
  59. unsigned char uc;
  60. if (__stdio_READ(stream, &uc, 1)) {
  61. return uc;
  62. }
  63. }
  64. }
  65. return EOF;
  66. }
  67. #elif defined __UCLIBC_HAS_THREADS__
  68. weak_alias(fgetc,getc);
  69. int fgetc(register FILE *stream)
  70. {
  71. if (stream->__user_locking != 0) {
  72. return __GETC_UNLOCKED_MACRO(stream);
  73. } else {
  74. int retval;
  75. __STDIO_ALWAYS_THREADLOCK(stream);
  76. retval = __GETC_UNLOCKED_MACRO(stream);
  77. __STDIO_ALWAYS_THREADUNLOCK(stream);
  78. return retval;
  79. }
  80. }
  81. #endif