]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/unix/sysv/linux/procutils.c
Update copyright dates with scripts/update-copyrights
[thirdparty/glibc.git] / sysdeps / unix / sysv / linux / procutils.c
CommitLineData
e7190fc7 1/* Utilities functions to read/parse Linux procfs and sysfs.
dff8da6b 2 Copyright (C) 2023-2024 Free Software Foundation, Inc.
e7190fc7
AZN
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
18
19#include <assert.h>
20#include <not-cancel.h>
21#include <procutils.h>
22#include <string.h>
23
24static int
25next_line (char **r, int fd, char *const buffer, char **cp, char **re,
26 char *const buffer_end)
27{
28 char *res = *cp;
29 char *nl = memchr (*cp, '\n', *re - *cp);
30 if (nl == NULL)
31 {
32 if (*cp != buffer)
33 {
34 if (*re == buffer_end)
35 {
36 memmove (buffer, *cp, *re - *cp);
37 *re = buffer + (*re - *cp);
38 *cp = buffer;
39
40 ssize_t n = TEMP_FAILURE_RETRY (
41 __read_nocancel (fd, *re, buffer_end - *re));
42 if (n < 0)
43 return -1;
44
45 *re += n;
46
47 nl = memchr (*cp, '\n', *re - *cp);
48 if (nl == NULL)
49 /* Line too long. */
50 return 0;
51 }
52 else
53 nl = memchr (*cp, '\n', *re - *cp);
54
55 res = *cp;
56 }
57
58 if (nl == NULL)
59 nl = *re - 1;
60 }
61
62 *nl = '\0';
63 *cp = nl + 1;
64 assert (*cp <= *re);
65
66 if (res == *re)
67 return 0;
68
69 *r = res;
70 return 1;
71}
72
73bool
74procutils_read_file (const char *filename, procutils_closure_t closure,
75 void *arg)
76{
77 enum { buffer_size = PROCUTILS_MAX_LINE_LEN };
78 char buffer[buffer_size];
79 char *buffer_end = buffer + buffer_size;
80 char *cp = buffer_end;
81 char *re = buffer_end;
82
83 int fd = TEMP_FAILURE_RETRY (
84 __open64_nocancel (filename, O_RDONLY | O_CLOEXEC));
85 if (fd == -1)
86 return false;
87
88 char *l;
89 int r;
90 while ((r = next_line (&l, fd, buffer, &cp, &re, buffer_end)) > 0)
91 if (closure (l, arg) != 0)
92 break;
93
94 __close_nocancel_nostatus (fd);
95
96 return r == 1;
97}