posix_getline.c 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. /* posix_getline.c
  2. * RT-Thread POSIX
  3. * getdelim(), getline() - read a delimited record from stream, ersatz implementation
  4. * This code is unlicensed -- free and released into the public domain.
  5. * https://man7.org/linux/man-pages/man3/getline.3.html
  6. * Authors:
  7. * https://github.com/ivanrad/getline
  8. *
  9. * Meco Man 2020-09-03 porting to RT-Thread
  10. */
  11. #include "posix_getline.h"
  12. #include <stdlib.h>
  13. #include <limits.h>
  14. #include <sys/errno.h>
  15. ssize_t getdelim(char **lineptr, size_t *n, int delim, FILE *stream) {
  16. char *cur_pos, *new_lineptr;
  17. size_t new_lineptr_len;
  18. int c;
  19. if (lineptr == NULL || n == NULL || stream == NULL) {
  20. errno = EINVAL;
  21. return -1;
  22. }
  23. if (*lineptr == NULL) {
  24. *n = 128; /* init len */
  25. if ((*lineptr = (char *)malloc(*n)) == NULL) {
  26. errno = ENOMEM;
  27. return -1;
  28. }
  29. }
  30. cur_pos = *lineptr;
  31. for (;;) {
  32. c = getc(stream);
  33. if (ferror(stream) || (c == EOF && cur_pos == *lineptr))
  34. return -1;
  35. if (c == EOF)
  36. break;
  37. if ((*lineptr + *n - cur_pos) < 2) {
  38. if (LONG_MAX / 2 < *n) {
  39. #ifdef EOVERFLOW
  40. errno = EOVERFLOW;
  41. #else
  42. errno = ERANGE; /* no EOVERFLOW defined */
  43. #endif
  44. return -1;
  45. }
  46. new_lineptr_len = *n * 2;
  47. if ((new_lineptr = (char *)realloc(*lineptr, new_lineptr_len)) == NULL) {
  48. errno = ENOMEM;
  49. return -1;
  50. }
  51. cur_pos = new_lineptr + (cur_pos - *lineptr);
  52. *lineptr = new_lineptr;
  53. *n = new_lineptr_len;
  54. }
  55. *cur_pos++ = (char)c;
  56. if (c == delim)
  57. break;
  58. }
  59. *cur_pos = '\0';
  60. return (ssize_t)(cur_pos - *lineptr);
  61. }
  62. ssize_t getline(char **lineptr, size_t *n, FILE *stream) {
  63. return getdelim(lineptr, n, '\n', stream);
  64. }