linux: Add pidfd_getpid
[glibc.git] / sysdeps / unix / sysv / linux / procutils.c
blob30fc3a063ac9249eda72f3fe75e85be008a645c5
1 /* Utilities functions to read/parse Linux procfs and sysfs.
2 Copyright (C) 2023 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
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.
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.
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/>. */
19 #include <assert.h>
20 #include <not-cancel.h>
21 #include <procutils.h>
22 #include <string.h>
24 static int
25 next_line (char **r, int fd, char *const buffer, char **cp, char **re,
26 char *const buffer_end)
28 char *res = *cp;
29 char *nl = memchr (*cp, '\n', *re - *cp);
30 if (nl == NULL)
32 if (*cp != buffer)
34 if (*re == buffer_end)
36 memmove (buffer, *cp, *re - *cp);
37 *re = buffer + (*re - *cp);
38 *cp = buffer;
40 ssize_t n = TEMP_FAILURE_RETRY (
41 __read_nocancel (fd, *re, buffer_end - *re));
42 if (n < 0)
43 return -1;
45 *re += n;
47 nl = memchr (*cp, '\n', *re - *cp);
48 if (nl == NULL)
49 /* Line too long. */
50 return 0;
52 else
53 nl = memchr (*cp, '\n', *re - *cp);
55 res = *cp;
58 if (nl == NULL)
59 nl = *re - 1;
62 *nl = '\0';
63 *cp = nl + 1;
64 assert (*cp <= *re);
66 if (res == *re)
67 return 0;
69 *r = res;
70 return 1;
73 bool
74 procutils_read_file (const char *filename, procutils_closure_t closure,
75 void *arg)
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;
83 int fd = TEMP_FAILURE_RETRY (
84 __open64_nocancel (filename, O_RDONLY | O_CLOEXEC));
85 if (fd == -1)
86 return false;
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;
94 __close_nocancel_nostatus (fd);
96 return r == 1;