fgets.c 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  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. #ifdef __DO_UNLOCKED
  9. char attribute_hidden *__fgets_unlocked(char *__restrict s, int n,
  10. register FILE * __restrict stream)
  11. {
  12. register char *p;
  13. int c;
  14. __STDIO_STREAM_VALIDATE(stream);
  15. #ifdef __UCLIBC_MJN3_ONLY__
  16. #warning CONSIDER: What should fgets do if n <= 0?
  17. #endif /* __UCLIBC_MJN3_ONLY__ */
  18. /* Should we assert here? Or set errno? Or just fail... */
  19. if (n <= 0) {
  20. /* __set_errno(EINVAL); */
  21. goto ERROR;
  22. }
  23. p = s;
  24. while (--n) {
  25. if (__STDIO_STREAM_CAN_USE_BUFFER_GET(stream)) {
  26. if ((*p++ = __STDIO_STREAM_BUFFER_GET(stream)) == '\n') {
  27. break;
  28. }
  29. } else {
  30. if ((c = __fgetc_unlocked_internal(stream)) == EOF) {
  31. if (__FERROR_UNLOCKED(stream)) {
  32. goto ERROR;
  33. }
  34. break;
  35. }
  36. if ((*p++ = c) == '\n') {
  37. break;
  38. }
  39. }
  40. }
  41. #ifdef __UCLIBC_MJN3_ONLY__
  42. #warning CONSIDER: If n==1 and not at EOF, should fgets return an empty string?
  43. #endif /* __UCLIBC_MJN3_ONLY__ */
  44. if (p > s) {
  45. *p = 0;
  46. return s;
  47. }
  48. ERROR:
  49. return NULL;
  50. }
  51. weak_alias(__fgets_unlocked,fgets_unlocked)
  52. #ifndef __UCLIBC_HAS_THREADS__
  53. hidden_strong_alias(__fgets_unlocked,__fgets)
  54. weak_alias(__fgets_unlocked,fgets)
  55. #endif
  56. #elif defined __UCLIBC_HAS_THREADS__
  57. char attribute_hidden *__fgets(char *__restrict s, int n,
  58. register FILE * __restrict stream)
  59. {
  60. char *retval;
  61. __STDIO_AUTO_THREADLOCK_VAR;
  62. __STDIO_AUTO_THREADLOCK(stream);
  63. retval = __fgets_unlocked(s, n, stream);
  64. __STDIO_AUTO_THREADUNLOCK(stream);
  65. return retval;
  66. }
  67. strong_alias(__fgets,fgets)
  68. #endif