fgetgrent_r.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. /* Copyright (C) 1991-2019 Free Software Foundation, Inc.
  2. This file is part of the GNU C Library.
  3. The GNU C Library is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU Lesser General Public
  5. License as published by the Free Software Foundation; either
  6. version 2.1 of the License, or (at your option) any later version.
  7. The GNU C Library is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10. Lesser General Public License for more details.
  11. You should have received a copy of the GNU Lesser General Public
  12. License along with the GNU C Library; if not, see
  13. <http://www.gnu.org/licenses/>. */
  14. #include <ctype.h>
  15. #include <errno.h>
  16. #include <grp.h>
  17. #include <stdio.h>
  18. #include <libio/iolibio.h>
  19. #define flockfile(s) _IO_flockfile (s)
  20. #define funlockfile(s) _IO_funlockfile (s)
  21. /* Define a line parsing function using the common code
  22. used in the nss_files module. */
  23. #define STRUCTURE group
  24. #define ENTNAME grent
  25. struct grent_data {};
  26. #define TRAILING_LIST_MEMBER gr_mem
  27. #define TRAILING_LIST_SEPARATOR_P(c) ((c) == ',')
  28. #include <nss/nss_files/files-parse.c>
  29. LINE_PARSER
  30. (,
  31. STRING_FIELD (result->gr_name, ISCOLON, 0);
  32. if (line[0] == '\0'
  33. && (result->gr_name[0] == '+' || result->gr_name[0] == '-'))
  34. {
  35. result->gr_passwd = NULL;
  36. result->gr_gid = 0;
  37. }
  38. else
  39. {
  40. STRING_FIELD (result->gr_passwd, ISCOLON, 0);
  41. if (result->gr_name[0] == '+' || result->gr_name[0] == '-')
  42. INT_FIELD_MAYBE_NULL (result->gr_gid, ISCOLON, 0, 10, , 0)
  43. else
  44. INT_FIELD (result->gr_gid, ISCOLON, 0, 10,)
  45. }
  46. )
  47. /* Read one entry from the given stream. */
  48. int
  49. __fgetgrent_r (FILE *stream, struct group *resbuf, char *buffer, size_t buflen,
  50. struct group **result)
  51. {
  52. char *p;
  53. int parse_result;
  54. flockfile (stream);
  55. do
  56. {
  57. buffer[buflen - 1] = '\xff';
  58. p = fgets_unlocked (buffer, buflen, stream);
  59. if (__builtin_expect (p == NULL, 0) && feof_unlocked (stream))
  60. {
  61. funlockfile (stream);
  62. *result = NULL;
  63. __set_errno (ENOENT);
  64. return errno;
  65. }
  66. if (__builtin_expect (p == NULL, 0) || buffer[buflen - 1] != '\xff')
  67. {
  68. funlockfile (stream);
  69. *result = NULL;
  70. __set_errno (ERANGE);
  71. return errno;
  72. }
  73. /* Skip leading blanks. */
  74. while (isspace (*p))
  75. ++p;
  76. } while (*p == '\0' || *p == '#' /* Ignore empty and comment lines. */
  77. /* Parse the line. If it is invalid, loop to
  78. get the next line of the file to parse. */
  79. || ! (parse_result = parse_line (p, resbuf,
  80. (void *) buffer, buflen,
  81. &errno)));
  82. funlockfile (stream);
  83. if (__builtin_expect (parse_result, 0) == -1)
  84. {
  85. /* The parser ran out of space. */
  86. *result = NULL;
  87. return errno;
  88. }
  89. *result = resbuf;
  90. return 0;
  91. }
  92. weak_alias (__fgetgrent_r, fgetgrent_r)