fgets.c 1.6 KB

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