diff options
author | Adhemerval Zanella Netto <adhemerval.zanella@linaro.org> | 2023-08-24 13:42:19 -0300 |
---|---|---|
committer | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2023-09-05 13:08:59 -0300 |
commit | e7190fc73dbc8a1f8f94f8ccacd9a190fa5e609c (patch) | |
tree | 0070895e116c7250463b90b643f8727466bfbb5b /sysdeps/unix/sysv/linux/procutils.c | |
parent | 0d6f9f626521678f330f8bfee89e1cdb7e2b1062 (diff) | |
download | glibc-e7190fc73dbc8a1f8f94f8ccacd9a190fa5e609c.zip glibc-e7190fc73dbc8a1f8f94f8ccacd9a190fa5e609c.tar.gz glibc-e7190fc73dbc8a1f8f94f8ccacd9a190fa5e609c.tar.bz2 |
linux: Add pidfd_getpid
This interface allows to obtain the associated process ID from the
process file descriptor. It is done by parsing the procps fdinfo
information. Its prototype is:
pid_t pidfd_getpid (int fd)
It returns the associated pid or -1 in case of an error and sets the
errno accordingly. The possible errno values are those from open, read,
and close (used on procps parsing), along with:
- EBADF if the FD is negative, does not have a PID associated, or if
the fdinfo fields contain a value larger than pid_t.
- EREMOTE if the PID is in a separate namespace.
- ESRCH if the process is already terminated.
Checked on x86_64-linux-gnu on Linux 4.15 (no CLONE_PIDFD or waitid
support), Linux 5.4 (full support), and Linux 6.2.
Reviewed-by: Florian Weimer <fweimer@redhat.com>
Diffstat (limited to 'sysdeps/unix/sysv/linux/procutils.c')
-rw-r--r-- | sysdeps/unix/sysv/linux/procutils.c | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/sysdeps/unix/sysv/linux/procutils.c b/sysdeps/unix/sysv/linux/procutils.c new file mode 100644 index 0000000..30fc3a0 --- /dev/null +++ b/sysdeps/unix/sysv/linux/procutils.c @@ -0,0 +1,97 @@ +/* Utilities functions to read/parse Linux procfs and sysfs. + Copyright (C) 2023 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +#include <assert.h> +#include <not-cancel.h> +#include <procutils.h> +#include <string.h> + +static int +next_line (char **r, int fd, char *const buffer, char **cp, char **re, + char *const buffer_end) +{ + char *res = *cp; + char *nl = memchr (*cp, '\n', *re - *cp); + if (nl == NULL) + { + if (*cp != buffer) + { + if (*re == buffer_end) + { + memmove (buffer, *cp, *re - *cp); + *re = buffer + (*re - *cp); + *cp = buffer; + + ssize_t n = TEMP_FAILURE_RETRY ( + __read_nocancel (fd, *re, buffer_end - *re)); + if (n < 0) + return -1; + + *re += n; + + nl = memchr (*cp, '\n', *re - *cp); + if (nl == NULL) + /* Line too long. */ + return 0; + } + else + nl = memchr (*cp, '\n', *re - *cp); + + res = *cp; + } + + if (nl == NULL) + nl = *re - 1; + } + + *nl = '\0'; + *cp = nl + 1; + assert (*cp <= *re); + + if (res == *re) + return 0; + + *r = res; + return 1; +} + +bool +procutils_read_file (const char *filename, procutils_closure_t closure, + void *arg) +{ + enum { buffer_size = PROCUTILS_MAX_LINE_LEN }; + char buffer[buffer_size]; + char *buffer_end = buffer + buffer_size; + char *cp = buffer_end; + char *re = buffer_end; + + int fd = TEMP_FAILURE_RETRY ( + __open64_nocancel (filename, O_RDONLY | O_CLOEXEC)); + if (fd == -1) + return false; + + char *l; + int r; + while ((r = next_line (&l, fd, buffer, &cp, &re, buffer_end)) > 0) + if (closure (l, arg) != 0) + break; + + __close_nocancel_nostatus (fd); + + return r == 1; +} |