1 /* pidfd_getpid - Get the associated pid from the pid file descriptor.
2 Copyright (C) 2023-2024 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/>. */
22 #include <procutils.h>
28 #define FDINFO_TO_FILENAME_PREFIX "/proc/self/fdinfo/"
30 #define FDINFO_FILENAME_LEN \
31 (sizeof (FDINFO_TO_FILENAME_PREFIX) + INT_STRLEN_BOUND (int))
39 /* Parse the PID field in the fdinfo entry, if existent. Avoid strtol or
40 similar to not be locale dependent. */
42 parse_fdinfo (const char *l
, void *arg
)
44 enum { fieldlen
= sizeof ("Pid:") - 1 };
45 if (strncmp (l
, "Pid:", fieldlen
) != 0)
50 /* Skip leading spaces. */
51 while (*l
== ' ' || (unsigned int) (*l
) -'\t' < 5)
71 /* Check if '*l' is a digit. */
72 if ('0' > *l
|| *l
> '9')
75 /* Ignore invalid large values. */
76 if (INT_MULTIPLY_WRAPV (10, n
, &n
)
77 || INT_ADD_WRAPV (n
, *l
++ - '0', &n
))
81 /* -1 indicates that the process is terminated. */
85 struct parse_fdinfo_t
*fdinfo
= arg
;
86 fdinfo
->pid
= neg
? -n
: n
;
95 if (__glibc_unlikely (fd
< 0))
101 char fdinfoname
[FDINFO_FILENAME_LEN
];
103 char *p
= mempcpy (fdinfoname
, FDINFO_TO_FILENAME_PREFIX
,
104 strlen (FDINFO_TO_FILENAME_PREFIX
));
105 *_fitoa_word (fd
, p
, 10, 0) = '\0';
107 struct parse_fdinfo_t fdinfo
= { .found
= false, .pid
= -1 };
108 if (!procutils_read_file (fdinfoname
, parse_fdinfo
, &fdinfo
))
109 /* The fdinfo contains an invalid 'Pid:' value. */
110 return INLINE_SYSCALL_ERROR_RETURN_VALUE (EBADF
);
112 /* The FD does not have a 'Pid:' entry associated. */
114 return INLINE_SYSCALL_ERROR_RETURN_VALUE (EBADF
);
116 /* The pidfd cannot be resolved because it is in a separate pid
119 return INLINE_SYSCALL_ERROR_RETURN_VALUE (EREMOTE
);
121 /* A negative value means the process is terminated. */
123 return INLINE_SYSCALL_ERROR_RETURN_VALUE (ESRCH
);