mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-26 23:10:06 +00:00
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>
This commit is contained in:
parent
0d6f9f6265
commit
e7190fc73d
4
NEWS
4
NEWS
@ -27,6 +27,10 @@ Major new features:
|
|||||||
The pidfd functionality avoids the issue of PID reuse with the traditional
|
The pidfd functionality avoids the issue of PID reuse with the traditional
|
||||||
posix_spawn interface.
|
posix_spawn interface.
|
||||||
|
|
||||||
|
* On Linux, the pidfd_getpid function has been added. It allows retrieving
|
||||||
|
the process ID associated with the process file descriptor created by
|
||||||
|
pid_spawn, fork_np, or pidfd_open.
|
||||||
|
|
||||||
Deprecated and removed features, and other changes affecting compatibility:
|
Deprecated and removed features, and other changes affecting compatibility:
|
||||||
|
|
||||||
[Add deprecations, removals and changes affecting compatibility here]
|
[Add deprecations, removals and changes affecting compatibility here]
|
||||||
|
@ -33,6 +33,7 @@ primitive functions to do each step individually instead.
|
|||||||
* Process Creation Concepts:: An overview of the hard way to do it.
|
* Process Creation Concepts:: An overview of the hard way to do it.
|
||||||
* Process Identification:: How to get the process ID of a process.
|
* Process Identification:: How to get the process ID of a process.
|
||||||
* Creating a Process:: How to fork a child process.
|
* Creating a Process:: How to fork a child process.
|
||||||
|
* Querying a Process:: How to query a child process.
|
||||||
* Executing a File:: How to make a process execute another program.
|
* Executing a File:: How to make a process execute another program.
|
||||||
* Process Completion:: How to tell when a child process has completed.
|
* Process Completion:: How to tell when a child process has completed.
|
||||||
* Process Completion Status:: How to interpret the status value
|
* Process Completion Status:: How to interpret the status value
|
||||||
@ -362,6 +363,43 @@ the proper precautions for using @code{vfork}, your program will still
|
|||||||
work even if the system uses @code{fork} instead.
|
work even if the system uses @code{fork} instead.
|
||||||
@end deftypefun
|
@end deftypefun
|
||||||
|
|
||||||
|
@node Querying a Process
|
||||||
|
@section Querying a Process
|
||||||
|
|
||||||
|
The file descriptor returned by the @code{pidfd_fork} function can be used to
|
||||||
|
query process extra information.
|
||||||
|
|
||||||
|
@deftypefun pid_t pidfd_getpid (int @var{fd})
|
||||||
|
@standards{GNU, sys/pidfd.h}
|
||||||
|
@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
|
||||||
|
|
||||||
|
The @code{pidfd_getpid} function retrieves the process ID associated with process
|
||||||
|
file descriptor created with @code{pid_spawn}, @code{pidfd_fork}, or
|
||||||
|
@code{pidfd_open}.
|
||||||
|
|
||||||
|
If the operation fails, @code{pidfd_getpid} return @code{-1} and the following
|
||||||
|
@code{errno} error conditionas are defined:
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
@item EBADF
|
||||||
|
The input file descriptor is invalid, does not have a pidfd associated, or an
|
||||||
|
error has occurred parsing the kernel data.
|
||||||
|
@item EREMOTE
|
||||||
|
There is no process ID to denote the process in the current namespace.
|
||||||
|
@item ESRCH
|
||||||
|
The process for which the file descriptor refers to is terminated.
|
||||||
|
@item ENOENT
|
||||||
|
The procfs is not mounted.
|
||||||
|
@item ENFILE.
|
||||||
|
Too many open files in system (@code{pidfd_open} tries to open a procfs file and
|
||||||
|
read its contents).
|
||||||
|
@item ENOMEM
|
||||||
|
Insufficient kernel memory was available.
|
||||||
|
@end table
|
||||||
|
|
||||||
|
This function is specific to Linux.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
@node Executing a File
|
@node Executing a File
|
||||||
@section Executing a File
|
@section Executing a File
|
||||||
@cindex executing a file
|
@cindex executing a file
|
||||||
|
@ -213,6 +213,7 @@ tests += \
|
|||||||
tst-ofdlocks \
|
tst-ofdlocks \
|
||||||
tst-personality \
|
tst-personality \
|
||||||
tst-pidfd \
|
tst-pidfd \
|
||||||
|
tst-pidfd_getpid \
|
||||||
tst-pkey \
|
tst-pkey \
|
||||||
tst-ppoll \
|
tst-ppoll \
|
||||||
tst-prctl \
|
tst-prctl \
|
||||||
@ -493,8 +494,10 @@ sysdep_headers += \
|
|||||||
sysdep_routines += \
|
sysdep_routines += \
|
||||||
getcpu \
|
getcpu \
|
||||||
oldglob \
|
oldglob \
|
||||||
|
pidfd_getpid \
|
||||||
pidfd_spawn \
|
pidfd_spawn \
|
||||||
pidfd_spawnp \
|
pidfd_spawnp \
|
||||||
|
procutils \
|
||||||
sched_getcpu \
|
sched_getcpu \
|
||||||
spawnattr_getcgroup_np \
|
spawnattr_getcgroup_np \
|
||||||
spawnattr_setcgroup_np \
|
spawnattr_setcgroup_np \
|
||||||
|
@ -322,6 +322,7 @@ libc {
|
|||||||
%endif
|
%endif
|
||||||
}
|
}
|
||||||
GLIBC_2.39 {
|
GLIBC_2.39 {
|
||||||
|
pidfd_getpid;
|
||||||
pidfd_spawn;
|
pidfd_spawn;
|
||||||
pidfd_spawnp;
|
pidfd_spawnp;
|
||||||
posix_spawnattr_getcgroup_np;
|
posix_spawnattr_getcgroup_np;
|
||||||
|
@ -2673,6 +2673,7 @@ GLIBC_2.38 strlcat F
|
|||||||
GLIBC_2.38 strlcpy F
|
GLIBC_2.38 strlcpy F
|
||||||
GLIBC_2.38 wcslcat F
|
GLIBC_2.38 wcslcat F
|
||||||
GLIBC_2.38 wcslcpy F
|
GLIBC_2.38 wcslcpy F
|
||||||
|
GLIBC_2.39 pidfd_getpid F
|
||||||
GLIBC_2.39 pidfd_spawn F
|
GLIBC_2.39 pidfd_spawn F
|
||||||
GLIBC_2.39 pidfd_spawnp F
|
GLIBC_2.39 pidfd_spawnp F
|
||||||
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
||||||
|
@ -2782,6 +2782,7 @@ GLIBC_2.38 strlcat F
|
|||||||
GLIBC_2.38 strlcpy F
|
GLIBC_2.38 strlcpy F
|
||||||
GLIBC_2.38 wcslcat F
|
GLIBC_2.38 wcslcat F
|
||||||
GLIBC_2.38 wcslcpy F
|
GLIBC_2.38 wcslcpy F
|
||||||
|
GLIBC_2.39 pidfd_getpid F
|
||||||
GLIBC_2.39 pidfd_spawn F
|
GLIBC_2.39 pidfd_spawn F
|
||||||
GLIBC_2.39 pidfd_spawnp F
|
GLIBC_2.39 pidfd_spawnp F
|
||||||
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
||||||
|
@ -2434,6 +2434,7 @@ GLIBC_2.38 strlcat F
|
|||||||
GLIBC_2.38 strlcpy F
|
GLIBC_2.38 strlcpy F
|
||||||
GLIBC_2.38 wcslcat F
|
GLIBC_2.38 wcslcat F
|
||||||
GLIBC_2.38 wcslcpy F
|
GLIBC_2.38 wcslcpy F
|
||||||
|
GLIBC_2.39 pidfd_getpid F
|
||||||
GLIBC_2.39 pidfd_spawn F
|
GLIBC_2.39 pidfd_spawn F
|
||||||
GLIBC_2.39 pidfd_spawnp F
|
GLIBC_2.39 pidfd_spawnp F
|
||||||
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
||||||
|
@ -554,6 +554,7 @@ GLIBC_2.38 strlcat F
|
|||||||
GLIBC_2.38 strlcpy F
|
GLIBC_2.38 strlcpy F
|
||||||
GLIBC_2.38 wcslcat F
|
GLIBC_2.38 wcslcat F
|
||||||
GLIBC_2.38 wcslcpy F
|
GLIBC_2.38 wcslcpy F
|
||||||
|
GLIBC_2.39 pidfd_getpid F
|
||||||
GLIBC_2.39 pidfd_spawn F
|
GLIBC_2.39 pidfd_spawn F
|
||||||
GLIBC_2.39 pidfd_spawnp F
|
GLIBC_2.39 pidfd_spawnp F
|
||||||
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
||||||
|
@ -551,6 +551,7 @@ GLIBC_2.38 strlcat F
|
|||||||
GLIBC_2.38 strlcpy F
|
GLIBC_2.38 strlcpy F
|
||||||
GLIBC_2.38 wcslcat F
|
GLIBC_2.38 wcslcat F
|
||||||
GLIBC_2.38 wcslcpy F
|
GLIBC_2.38 wcslcpy F
|
||||||
|
GLIBC_2.39 pidfd_getpid F
|
||||||
GLIBC_2.39 pidfd_spawn F
|
GLIBC_2.39 pidfd_spawn F
|
||||||
GLIBC_2.39 pidfd_spawnp F
|
GLIBC_2.39 pidfd_spawnp F
|
||||||
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
||||||
|
@ -2710,6 +2710,7 @@ GLIBC_2.38 strlcat F
|
|||||||
GLIBC_2.38 strlcpy F
|
GLIBC_2.38 strlcpy F
|
||||||
GLIBC_2.38 wcslcat F
|
GLIBC_2.38 wcslcat F
|
||||||
GLIBC_2.38 wcslcpy F
|
GLIBC_2.38 wcslcpy F
|
||||||
|
GLIBC_2.39 pidfd_getpid F
|
||||||
GLIBC_2.39 pidfd_spawn F
|
GLIBC_2.39 pidfd_spawn F
|
||||||
GLIBC_2.39 pidfd_spawnp F
|
GLIBC_2.39 pidfd_spawnp F
|
||||||
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
||||||
|
@ -2659,6 +2659,7 @@ GLIBC_2.38 strlcat F
|
|||||||
GLIBC_2.38 strlcpy F
|
GLIBC_2.38 strlcpy F
|
||||||
GLIBC_2.38 wcslcat F
|
GLIBC_2.38 wcslcat F
|
||||||
GLIBC_2.38 wcslcpy F
|
GLIBC_2.38 wcslcpy F
|
||||||
|
GLIBC_2.39 pidfd_getpid F
|
||||||
GLIBC_2.39 pidfd_spawn F
|
GLIBC_2.39 pidfd_spawn F
|
||||||
GLIBC_2.39 pidfd_spawnp F
|
GLIBC_2.39 pidfd_spawnp F
|
||||||
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
||||||
|
@ -2843,6 +2843,7 @@ GLIBC_2.38 strlcat F
|
|||||||
GLIBC_2.38 strlcpy F
|
GLIBC_2.38 strlcpy F
|
||||||
GLIBC_2.38 wcslcat F
|
GLIBC_2.38 wcslcat F
|
||||||
GLIBC_2.38 wcslcpy F
|
GLIBC_2.38 wcslcpy F
|
||||||
|
GLIBC_2.39 pidfd_getpid F
|
||||||
GLIBC_2.39 pidfd_spawn F
|
GLIBC_2.39 pidfd_spawn F
|
||||||
GLIBC_2.39 pidfd_spawnp F
|
GLIBC_2.39 pidfd_spawnp F
|
||||||
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
||||||
|
@ -2608,6 +2608,7 @@ GLIBC_2.38 strlcat F
|
|||||||
GLIBC_2.38 strlcpy F
|
GLIBC_2.38 strlcpy F
|
||||||
GLIBC_2.38 wcslcat F
|
GLIBC_2.38 wcslcat F
|
||||||
GLIBC_2.38 wcslcpy F
|
GLIBC_2.38 wcslcpy F
|
||||||
|
GLIBC_2.39 pidfd_getpid F
|
||||||
GLIBC_2.39 pidfd_spawn F
|
GLIBC_2.39 pidfd_spawn F
|
||||||
GLIBC_2.39 pidfd_spawnp F
|
GLIBC_2.39 pidfd_spawnp F
|
||||||
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
||||||
|
@ -2194,6 +2194,7 @@ GLIBC_2.38 strlcat F
|
|||||||
GLIBC_2.38 strlcpy F
|
GLIBC_2.38 strlcpy F
|
||||||
GLIBC_2.38 wcslcat F
|
GLIBC_2.38 wcslcat F
|
||||||
GLIBC_2.38 wcslcpy F
|
GLIBC_2.38 wcslcpy F
|
||||||
|
GLIBC_2.39 pidfd_getpid F
|
||||||
GLIBC_2.39 pidfd_spawn F
|
GLIBC_2.39 pidfd_spawn F
|
||||||
GLIBC_2.39 pidfd_spawnp F
|
GLIBC_2.39 pidfd_spawnp F
|
||||||
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
||||||
|
@ -555,6 +555,7 @@ GLIBC_2.38 strlcat F
|
|||||||
GLIBC_2.38 strlcpy F
|
GLIBC_2.38 strlcpy F
|
||||||
GLIBC_2.38 wcslcat F
|
GLIBC_2.38 wcslcat F
|
||||||
GLIBC_2.38 wcslcpy F
|
GLIBC_2.38 wcslcpy F
|
||||||
|
GLIBC_2.39 pidfd_getpid F
|
||||||
GLIBC_2.39 pidfd_spawn F
|
GLIBC_2.39 pidfd_spawn F
|
||||||
GLIBC_2.39 pidfd_spawnp F
|
GLIBC_2.39 pidfd_spawnp F
|
||||||
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
||||||
|
@ -2786,6 +2786,7 @@ GLIBC_2.38 strlcat F
|
|||||||
GLIBC_2.38 strlcpy F
|
GLIBC_2.38 strlcpy F
|
||||||
GLIBC_2.38 wcslcat F
|
GLIBC_2.38 wcslcat F
|
||||||
GLIBC_2.38 wcslcpy F
|
GLIBC_2.38 wcslcpy F
|
||||||
|
GLIBC_2.39 pidfd_getpid F
|
||||||
GLIBC_2.39 pidfd_spawn F
|
GLIBC_2.39 pidfd_spawn F
|
||||||
GLIBC_2.39 pidfd_spawnp F
|
GLIBC_2.39 pidfd_spawnp F
|
||||||
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
||||||
|
@ -2759,6 +2759,7 @@ GLIBC_2.38 strlcat F
|
|||||||
GLIBC_2.38 strlcpy F
|
GLIBC_2.38 strlcpy F
|
||||||
GLIBC_2.38 wcslcat F
|
GLIBC_2.38 wcslcat F
|
||||||
GLIBC_2.38 wcslcpy F
|
GLIBC_2.38 wcslcpy F
|
||||||
|
GLIBC_2.39 pidfd_getpid F
|
||||||
GLIBC_2.39 pidfd_spawn F
|
GLIBC_2.39 pidfd_spawn F
|
||||||
GLIBC_2.39 pidfd_spawnp F
|
GLIBC_2.39 pidfd_spawnp F
|
||||||
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
||||||
|
@ -2756,6 +2756,7 @@ GLIBC_2.38 strlcat F
|
|||||||
GLIBC_2.38 strlcpy F
|
GLIBC_2.38 strlcpy F
|
||||||
GLIBC_2.38 wcslcat F
|
GLIBC_2.38 wcslcat F
|
||||||
GLIBC_2.38 wcslcpy F
|
GLIBC_2.38 wcslcpy F
|
||||||
|
GLIBC_2.39 pidfd_getpid F
|
||||||
GLIBC_2.39 pidfd_spawn F
|
GLIBC_2.39 pidfd_spawn F
|
||||||
GLIBC_2.39 pidfd_spawnp F
|
GLIBC_2.39 pidfd_spawnp F
|
||||||
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
||||||
|
@ -2751,6 +2751,7 @@ GLIBC_2.38 strlcat F
|
|||||||
GLIBC_2.38 strlcpy F
|
GLIBC_2.38 strlcpy F
|
||||||
GLIBC_2.38 wcslcat F
|
GLIBC_2.38 wcslcat F
|
||||||
GLIBC_2.38 wcslcpy F
|
GLIBC_2.38 wcslcpy F
|
||||||
|
GLIBC_2.39 pidfd_getpid F
|
||||||
GLIBC_2.39 pidfd_spawn F
|
GLIBC_2.39 pidfd_spawn F
|
||||||
GLIBC_2.39 pidfd_spawnp F
|
GLIBC_2.39 pidfd_spawnp F
|
||||||
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
||||||
|
@ -2749,6 +2749,7 @@ GLIBC_2.38 strlcat F
|
|||||||
GLIBC_2.38 strlcpy F
|
GLIBC_2.38 strlcpy F
|
||||||
GLIBC_2.38 wcslcat F
|
GLIBC_2.38 wcslcat F
|
||||||
GLIBC_2.38 wcslcpy F
|
GLIBC_2.38 wcslcpy F
|
||||||
|
GLIBC_2.39 pidfd_getpid F
|
||||||
GLIBC_2.39 pidfd_spawn F
|
GLIBC_2.39 pidfd_spawn F
|
||||||
GLIBC_2.39 pidfd_spawnp F
|
GLIBC_2.39 pidfd_spawnp F
|
||||||
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
||||||
|
@ -2757,6 +2757,7 @@ GLIBC_2.38 strlcat F
|
|||||||
GLIBC_2.38 strlcpy F
|
GLIBC_2.38 strlcpy F
|
||||||
GLIBC_2.38 wcslcat F
|
GLIBC_2.38 wcslcat F
|
||||||
GLIBC_2.38 wcslcpy F
|
GLIBC_2.38 wcslcpy F
|
||||||
|
GLIBC_2.39 pidfd_getpid F
|
||||||
GLIBC_2.39 pidfd_spawn F
|
GLIBC_2.39 pidfd_spawn F
|
||||||
GLIBC_2.39 pidfd_spawnp F
|
GLIBC_2.39 pidfd_spawnp F
|
||||||
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
||||||
|
@ -2659,6 +2659,7 @@ GLIBC_2.38 strlcat F
|
|||||||
GLIBC_2.38 strlcpy F
|
GLIBC_2.38 strlcpy F
|
||||||
GLIBC_2.38 wcslcat F
|
GLIBC_2.38 wcslcat F
|
||||||
GLIBC_2.38 wcslcpy F
|
GLIBC_2.38 wcslcpy F
|
||||||
|
GLIBC_2.39 pidfd_getpid F
|
||||||
GLIBC_2.39 pidfd_spawn F
|
GLIBC_2.39 pidfd_spawn F
|
||||||
GLIBC_2.39 pidfd_spawnp F
|
GLIBC_2.39 pidfd_spawnp F
|
||||||
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
||||||
|
@ -2798,6 +2798,7 @@ GLIBC_2.38 strlcat F
|
|||||||
GLIBC_2.38 strlcpy F
|
GLIBC_2.38 strlcpy F
|
||||||
GLIBC_2.38 wcslcat F
|
GLIBC_2.38 wcslcat F
|
||||||
GLIBC_2.38 wcslcpy F
|
GLIBC_2.38 wcslcpy F
|
||||||
|
GLIBC_2.39 pidfd_getpid F
|
||||||
GLIBC_2.39 pidfd_spawn F
|
GLIBC_2.39 pidfd_spawn F
|
||||||
GLIBC_2.39 pidfd_spawnp F
|
GLIBC_2.39 pidfd_spawnp F
|
||||||
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
||||||
|
@ -2180,6 +2180,7 @@ GLIBC_2.38 strlcat F
|
|||||||
GLIBC_2.38 strlcpy F
|
GLIBC_2.38 strlcpy F
|
||||||
GLIBC_2.38 wcslcat F
|
GLIBC_2.38 wcslcat F
|
||||||
GLIBC_2.38 wcslcpy F
|
GLIBC_2.38 wcslcpy F
|
||||||
|
GLIBC_2.39 pidfd_getpid F
|
||||||
GLIBC_2.39 pidfd_spawn F
|
GLIBC_2.39 pidfd_spawn F
|
||||||
GLIBC_2.39 pidfd_spawnp F
|
GLIBC_2.39 pidfd_spawnp F
|
||||||
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
||||||
|
126
sysdeps/unix/sysv/linux/pidfd_getpid.c
Normal file
126
sysdeps/unix/sysv/linux/pidfd_getpid.c
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
/* pidfd_getpid - Get the associated pid from the pid file descriptor.
|
||||||
|
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 <_itoa.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <intprops.h>
|
||||||
|
#include <procutils.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sysdep.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#define FDINFO_TO_FILENAME_PREFIX "/proc/self/fdinfo/"
|
||||||
|
|
||||||
|
#define FDINFO_FILENAME_LEN \
|
||||||
|
(sizeof (FDINFO_TO_FILENAME_PREFIX) + INT_STRLEN_BOUND (int))
|
||||||
|
|
||||||
|
struct parse_fdinfo_t
|
||||||
|
{
|
||||||
|
bool found;
|
||||||
|
pid_t pid;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Parse the PID field in the fdinfo entry, if existent. Avoid strtol or
|
||||||
|
similar to not be locale dependent. */
|
||||||
|
static int
|
||||||
|
parse_fdinfo (const char *l, void *arg)
|
||||||
|
{
|
||||||
|
enum { fieldlen = sizeof ("Pid:") - 1 };
|
||||||
|
if (strncmp (l, "Pid:", fieldlen) != 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
l += fieldlen;
|
||||||
|
|
||||||
|
/* Skip leading spaces. */
|
||||||
|
while (*l == ' ' || (unsigned int) (*l) -'\t' < 5)
|
||||||
|
l++;
|
||||||
|
|
||||||
|
bool neg = false;
|
||||||
|
switch (*l)
|
||||||
|
{
|
||||||
|
case '-':
|
||||||
|
neg = true;
|
||||||
|
l++;
|
||||||
|
break;
|
||||||
|
case '+':
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*l == '\0')
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
int n = 0;
|
||||||
|
while (*l != '\0')
|
||||||
|
{
|
||||||
|
/* Check if '*l' is a digit. */
|
||||||
|
if ('0' > *l || *l > '9')
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Ignore invalid large values. */
|
||||||
|
if (INT_MULTIPLY_WRAPV (10, n, &n)
|
||||||
|
|| INT_ADD_WRAPV (n, *l++ - '0', &n))
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -1 indicates that the process is terminated. */
|
||||||
|
if (neg && n != 1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
struct parse_fdinfo_t *fdinfo = arg;
|
||||||
|
fdinfo->pid = neg ? -n : n;
|
||||||
|
fdinfo->found = true;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pid_t
|
||||||
|
pidfd_getpid (int fd)
|
||||||
|
{
|
||||||
|
if (__glibc_unlikely (fd < 0))
|
||||||
|
{
|
||||||
|
__set_errno (EBADF);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char fdinfoname[FDINFO_FILENAME_LEN];
|
||||||
|
|
||||||
|
char *p = mempcpy (fdinfoname, FDINFO_TO_FILENAME_PREFIX,
|
||||||
|
strlen (FDINFO_TO_FILENAME_PREFIX));
|
||||||
|
*_fitoa_word (fd, p, 10, 0) = '\0';
|
||||||
|
|
||||||
|
struct parse_fdinfo_t fdinfo = { .found = false, .pid = -1 };
|
||||||
|
if (!procutils_read_file (fdinfoname, parse_fdinfo, &fdinfo))
|
||||||
|
/* The fdinfo contains an invalid 'Pid:' value. */
|
||||||
|
return INLINE_SYSCALL_ERROR_RETURN_VALUE (EBADF);
|
||||||
|
|
||||||
|
/* The FD does not have a 'Pid:' entry associated. */
|
||||||
|
if (!fdinfo.found)
|
||||||
|
return INLINE_SYSCALL_ERROR_RETURN_VALUE (EBADF);
|
||||||
|
|
||||||
|
/* The pidfd cannot be resolved because it is in a separate pid
|
||||||
|
namespace. */
|
||||||
|
if (fdinfo.pid == 0)
|
||||||
|
return INLINE_SYSCALL_ERROR_RETURN_VALUE (EREMOTE);
|
||||||
|
|
||||||
|
/* A negative value means the process is terminated. */
|
||||||
|
if (fdinfo.pid < 0)
|
||||||
|
return INLINE_SYSCALL_ERROR_RETURN_VALUE (ESRCH);
|
||||||
|
|
||||||
|
return fdinfo.pid;
|
||||||
|
}
|
@ -2825,6 +2825,7 @@ GLIBC_2.38 strlcat F
|
|||||||
GLIBC_2.38 strlcpy F
|
GLIBC_2.38 strlcpy F
|
||||||
GLIBC_2.38 wcslcat F
|
GLIBC_2.38 wcslcat F
|
||||||
GLIBC_2.38 wcslcpy F
|
GLIBC_2.38 wcslcpy F
|
||||||
|
GLIBC_2.39 pidfd_getpid F
|
||||||
GLIBC_2.39 pidfd_spawn F
|
GLIBC_2.39 pidfd_spawn F
|
||||||
GLIBC_2.39 pidfd_spawnp F
|
GLIBC_2.39 pidfd_spawnp F
|
||||||
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
||||||
|
@ -2858,6 +2858,7 @@ GLIBC_2.38 strlcat F
|
|||||||
GLIBC_2.38 strlcpy F
|
GLIBC_2.38 strlcpy F
|
||||||
GLIBC_2.38 wcslcat F
|
GLIBC_2.38 wcslcat F
|
||||||
GLIBC_2.38 wcslcpy F
|
GLIBC_2.38 wcslcpy F
|
||||||
|
GLIBC_2.39 pidfd_getpid F
|
||||||
GLIBC_2.39 pidfd_spawn F
|
GLIBC_2.39 pidfd_spawn F
|
||||||
GLIBC_2.39 pidfd_spawnp F
|
GLIBC_2.39 pidfd_spawnp F
|
||||||
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
||||||
|
@ -2579,6 +2579,7 @@ GLIBC_2.38 strlcat F
|
|||||||
GLIBC_2.38 strlcpy F
|
GLIBC_2.38 strlcpy F
|
||||||
GLIBC_2.38 wcslcat F
|
GLIBC_2.38 wcslcat F
|
||||||
GLIBC_2.38 wcslcpy F
|
GLIBC_2.38 wcslcpy F
|
||||||
|
GLIBC_2.39 pidfd_getpid F
|
||||||
GLIBC_2.39 pidfd_spawn F
|
GLIBC_2.39 pidfd_spawn F
|
||||||
GLIBC_2.39 pidfd_spawnp F
|
GLIBC_2.39 pidfd_spawnp F
|
||||||
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
||||||
|
@ -2893,6 +2893,7 @@ GLIBC_2.38 strlcat F
|
|||||||
GLIBC_2.38 strlcpy F
|
GLIBC_2.38 strlcpy F
|
||||||
GLIBC_2.38 wcslcat F
|
GLIBC_2.38 wcslcat F
|
||||||
GLIBC_2.38 wcslcpy F
|
GLIBC_2.38 wcslcpy F
|
||||||
|
GLIBC_2.39 pidfd_getpid F
|
||||||
GLIBC_2.39 pidfd_spawn F
|
GLIBC_2.39 pidfd_spawn F
|
||||||
GLIBC_2.39 pidfd_spawnp F
|
GLIBC_2.39 pidfd_spawnp F
|
||||||
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
||||||
|
97
sysdeps/unix/sysv/linux/procutils.c
Normal file
97
sysdeps/unix/sysv/linux/procutils.c
Normal file
@ -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;
|
||||||
|
}
|
43
sysdeps/unix/sysv/linux/procutils.h
Normal file
43
sysdeps/unix/sysv/linux/procutils.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/* 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/>. */
|
||||||
|
|
||||||
|
#ifndef _PROCUTILS_H
|
||||||
|
#define _PROCUTILS_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
typedef int (*procutils_closure_t) (const char *line, void *arg);
|
||||||
|
|
||||||
|
#define PROCUTILS_MAX_LINE_LEN 256
|
||||||
|
|
||||||
|
/* Open and read the path FILENAME, line per line, and call CLOSURE with
|
||||||
|
argument ARG on each line. The read is done with a static buffer,
|
||||||
|
with non-cancellable calls, and the line is null terminated.
|
||||||
|
|
||||||
|
The CLOSURE should return 0 if the read should continue, otherwise the
|
||||||
|
the function should stop and return early.
|
||||||
|
|
||||||
|
The '\n' is not included in the CLOSURE input argument and lines longer
|
||||||
|
than PROCUTILS_MAX_LINE_LEN characteres are ignored.
|
||||||
|
|
||||||
|
It returns true in case the file is fully read or false if CLOSURE
|
||||||
|
returns a value diferent than 0. */
|
||||||
|
bool procutils_read_file (const char *filename, procutils_closure_t closure,
|
||||||
|
void *arg) attribute_hidden;
|
||||||
|
|
||||||
|
#endif
|
@ -2436,6 +2436,7 @@ GLIBC_2.38 strlcat F
|
|||||||
GLIBC_2.38 strlcpy F
|
GLIBC_2.38 strlcpy F
|
||||||
GLIBC_2.38 wcslcat F
|
GLIBC_2.38 wcslcat F
|
||||||
GLIBC_2.38 wcslcpy F
|
GLIBC_2.38 wcslcpy F
|
||||||
|
GLIBC_2.39 pidfd_getpid F
|
||||||
GLIBC_2.39 pidfd_spawn F
|
GLIBC_2.39 pidfd_spawn F
|
||||||
GLIBC_2.39 pidfd_spawnp F
|
GLIBC_2.39 pidfd_spawnp F
|
||||||
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
||||||
|
@ -2636,6 +2636,7 @@ GLIBC_2.38 strlcat F
|
|||||||
GLIBC_2.38 strlcpy F
|
GLIBC_2.38 strlcpy F
|
||||||
GLIBC_2.38 wcslcat F
|
GLIBC_2.38 wcslcat F
|
||||||
GLIBC_2.38 wcslcpy F
|
GLIBC_2.38 wcslcpy F
|
||||||
|
GLIBC_2.39 pidfd_getpid F
|
||||||
GLIBC_2.39 pidfd_spawn F
|
GLIBC_2.39 pidfd_spawn F
|
||||||
GLIBC_2.39 pidfd_spawnp F
|
GLIBC_2.39 pidfd_spawnp F
|
||||||
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
||||||
|
@ -2823,6 +2823,7 @@ GLIBC_2.38 strlcat F
|
|||||||
GLIBC_2.38 strlcpy F
|
GLIBC_2.38 strlcpy F
|
||||||
GLIBC_2.38 wcslcat F
|
GLIBC_2.38 wcslcat F
|
||||||
GLIBC_2.38 wcslcpy F
|
GLIBC_2.38 wcslcpy F
|
||||||
|
GLIBC_2.39 pidfd_getpid F
|
||||||
GLIBC_2.39 pidfd_spawn F
|
GLIBC_2.39 pidfd_spawn F
|
||||||
GLIBC_2.39 pidfd_spawnp F
|
GLIBC_2.39 pidfd_spawnp F
|
||||||
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
||||||
|
@ -2616,6 +2616,7 @@ GLIBC_2.38 strlcat F
|
|||||||
GLIBC_2.38 strlcpy F
|
GLIBC_2.38 strlcpy F
|
||||||
GLIBC_2.38 wcslcat F
|
GLIBC_2.38 wcslcat F
|
||||||
GLIBC_2.38 wcslcpy F
|
GLIBC_2.38 wcslcpy F
|
||||||
|
GLIBC_2.39 pidfd_getpid F
|
||||||
GLIBC_2.39 pidfd_spawn F
|
GLIBC_2.39 pidfd_spawn F
|
||||||
GLIBC_2.39 pidfd_spawnp F
|
GLIBC_2.39 pidfd_spawnp F
|
||||||
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
||||||
|
@ -2666,6 +2666,7 @@ GLIBC_2.38 strlcat F
|
|||||||
GLIBC_2.38 strlcpy F
|
GLIBC_2.38 strlcpy F
|
||||||
GLIBC_2.38 wcslcat F
|
GLIBC_2.38 wcslcat F
|
||||||
GLIBC_2.38 wcslcpy F
|
GLIBC_2.38 wcslcpy F
|
||||||
|
GLIBC_2.39 pidfd_getpid F
|
||||||
GLIBC_2.39 pidfd_spawn F
|
GLIBC_2.39 pidfd_spawn F
|
||||||
GLIBC_2.39 pidfd_spawnp F
|
GLIBC_2.39 pidfd_spawnp F
|
||||||
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
||||||
|
@ -2663,6 +2663,7 @@ GLIBC_2.38 strlcat F
|
|||||||
GLIBC_2.38 strlcpy F
|
GLIBC_2.38 strlcpy F
|
||||||
GLIBC_2.38 wcslcat F
|
GLIBC_2.38 wcslcat F
|
||||||
GLIBC_2.38 wcslcpy F
|
GLIBC_2.38 wcslcpy F
|
||||||
|
GLIBC_2.39 pidfd_getpid F
|
||||||
GLIBC_2.39 pidfd_spawn F
|
GLIBC_2.39 pidfd_spawn F
|
||||||
GLIBC_2.39 pidfd_spawnp F
|
GLIBC_2.39 pidfd_spawnp F
|
||||||
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
||||||
|
@ -2818,6 +2818,7 @@ GLIBC_2.38 strlcat F
|
|||||||
GLIBC_2.38 strlcpy F
|
GLIBC_2.38 strlcpy F
|
||||||
GLIBC_2.38 wcslcat F
|
GLIBC_2.38 wcslcat F
|
||||||
GLIBC_2.38 wcslcpy F
|
GLIBC_2.38 wcslcpy F
|
||||||
|
GLIBC_2.39 pidfd_getpid F
|
||||||
GLIBC_2.39 pidfd_spawn F
|
GLIBC_2.39 pidfd_spawn F
|
||||||
GLIBC_2.39 pidfd_spawnp F
|
GLIBC_2.39 pidfd_spawnp F
|
||||||
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
||||||
|
@ -2631,6 +2631,7 @@ GLIBC_2.38 strlcat F
|
|||||||
GLIBC_2.38 strlcpy F
|
GLIBC_2.38 strlcpy F
|
||||||
GLIBC_2.38 wcslcat F
|
GLIBC_2.38 wcslcat F
|
||||||
GLIBC_2.38 wcslcpy F
|
GLIBC_2.38 wcslcpy F
|
||||||
|
GLIBC_2.39 pidfd_getpid F
|
||||||
GLIBC_2.39 pidfd_spawn F
|
GLIBC_2.39 pidfd_spawn F
|
||||||
GLIBC_2.39 pidfd_spawnp F
|
GLIBC_2.39 pidfd_spawnp F
|
||||||
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
||||||
|
@ -46,4 +46,8 @@ extern int pidfd_getfd (int __pidfd, int __targetfd,
|
|||||||
extern int pidfd_send_signal (int __pidfd, int __sig, siginfo_t *__info,
|
extern int pidfd_send_signal (int __pidfd, int __sig, siginfo_t *__info,
|
||||||
unsigned int __flags) __THROW;
|
unsigned int __flags) __THROW;
|
||||||
|
|
||||||
|
/* Query the process ID (PID) from process descriptor FD. Return the PID
|
||||||
|
or -1 in case of an error. */
|
||||||
|
extern pid_t pidfd_getpid (int __fd) __THROW;
|
||||||
|
|
||||||
#endif /* _PIDFD_H */
|
#endif /* _PIDFD_H */
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <limits.h>
|
||||||
#include <support/capture_subprocess.h>
|
#include <support/capture_subprocess.h>
|
||||||
#include <support/check.h>
|
#include <support/check.h>
|
||||||
#include <support/process_state.h>
|
#include <support/process_state.h>
|
||||||
@ -27,6 +28,8 @@
|
|||||||
#include <support/xsocket.h>
|
#include <support/xsocket.h>
|
||||||
#include <sys/pidfd.h>
|
#include <sys/pidfd.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#define REMOTE_PATH "/dev/null"
|
#define REMOTE_PATH "/dev/null"
|
||||||
|
|
||||||
@ -102,6 +105,44 @@ do_test (void)
|
|||||||
ppid = getpid ();
|
ppid = getpid ();
|
||||||
puid = getuid ();
|
puid = getuid ();
|
||||||
|
|
||||||
|
/* Sanity check for invalid inputs. */
|
||||||
|
TEST_COMPARE (pidfd_getpid (-1), -1);
|
||||||
|
TEST_COMPARE (errno, EBADF);
|
||||||
|
|
||||||
|
{
|
||||||
|
pid_t pid = pidfd_getpid (STDOUT_FILENO);
|
||||||
|
TEST_COMPARE (pid, -1);
|
||||||
|
TEST_COMPARE (errno, EBADF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if pidfd_getpid returns ESRCH for exited subprocess. */
|
||||||
|
{
|
||||||
|
pid_t pidfork = xfork ();
|
||||||
|
if (pidfork == 0)
|
||||||
|
_exit (EXIT_SUCCESS);
|
||||||
|
int pidfork_pidfd = pidfd_open (pidfork, 0);
|
||||||
|
|
||||||
|
/* The process might be still running or already in zombie state, in
|
||||||
|
either case the PID is still allocated to the process. */
|
||||||
|
pid_t pid = pidfd_getpid (pidfork_pidfd);
|
||||||
|
TEST_COMPARE (pidfork, pid);
|
||||||
|
if (pid > 0)
|
||||||
|
support_process_state_wait (pid, support_process_state_zombie);
|
||||||
|
|
||||||
|
siginfo_t info;
|
||||||
|
TEST_COMPARE (waitid (P_PIDFD, pidfork_pidfd, &info, WEXITED), 0);
|
||||||
|
TEST_COMPARE (info.si_pid, pidfork);
|
||||||
|
TEST_COMPARE (info.si_status, 0);
|
||||||
|
TEST_COMPARE (info.si_code, CLD_EXITED);
|
||||||
|
|
||||||
|
/* Once the process is reaped the associated PID is not available. */
|
||||||
|
pid = pidfd_getpid (pidfork_pidfd);
|
||||||
|
TEST_COMPARE (pid, -1);
|
||||||
|
TEST_COMPARE (errno, ESRCH);
|
||||||
|
|
||||||
|
xclose (pidfork_pidfd);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_COMPARE (socketpair (AF_UNIX, SOCK_STREAM, 0, sockets), 0);
|
TEST_COMPARE (socketpair (AF_UNIX, SOCK_STREAM, 0, sockets), 0);
|
||||||
|
|
||||||
pid_t pid = xfork ();
|
pid_t pid = xfork ();
|
||||||
@ -118,6 +159,12 @@ do_test (void)
|
|||||||
int pidfd = pidfd_open (pid, 0);
|
int pidfd = pidfd_open (pid, 0);
|
||||||
TEST_VERIFY (pidfd != -1);
|
TEST_VERIFY (pidfd != -1);
|
||||||
|
|
||||||
|
TEST_COMPARE (pidfd_getpid (INT_MAX), -1);
|
||||||
|
{
|
||||||
|
pid_t querypid = pidfd_getpid (pidfd);
|
||||||
|
TEST_COMPARE (querypid, pid);
|
||||||
|
}
|
||||||
|
|
||||||
/* Wait for first sigtimedwait. */
|
/* Wait for first sigtimedwait. */
|
||||||
support_process_state_wait (pid, support_process_state_sleeping);
|
support_process_state_wait (pid, support_process_state_sleeping);
|
||||||
TEST_COMPARE (pidfd_send_signal (pidfd, SIGUSR1, NULL, 0), 0);
|
TEST_COMPARE (pidfd_send_signal (pidfd, SIGUSR1, NULL, 0), 0);
|
||||||
|
123
sysdeps/unix/sysv/linux/tst-pidfd_getpid.c
Normal file
123
sysdeps/unix/sysv/linux/tst-pidfd_getpid.c
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
/* Specific tests for Linux pidfd_getpid.
|
||||||
|
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 <errno.h>
|
||||||
|
#include <sched.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <support/check.h>
|
||||||
|
#include <support/xunistd.h>
|
||||||
|
#include <support/test-driver.h>
|
||||||
|
#include <sys/pidfd.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <sys/mount.h>
|
||||||
|
|
||||||
|
static int
|
||||||
|
do_test (void)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
/* The pidfd_getfd syscall was the last in the set of pidfd related
|
||||||
|
syscalls added to the kernel. Use pidfd_getfd to decide if this
|
||||||
|
kernel has pidfd support that we can test. */
|
||||||
|
int r = pidfd_getfd (0, 0, 1);
|
||||||
|
TEST_VERIFY_EXIT (r == -1);
|
||||||
|
if (errno == ENOSYS)
|
||||||
|
FAIL_UNSUPPORTED ("kernel does not support pidfd_getfd, skipping test");
|
||||||
|
if (errno == EPERM)
|
||||||
|
FAIL_UNSUPPORTED ("kernel does not allow pidfd_getfd, skipping test");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if pidfd_getpid returns EREMOTE for process not in current
|
||||||
|
namespace. */
|
||||||
|
{
|
||||||
|
pid_t child0 = xfork ();
|
||||||
|
TEST_VERIFY_EXIT (child0 >= 0);
|
||||||
|
if (child0 == 0)
|
||||||
|
{
|
||||||
|
/* Create another unrelated descriptor, so child2 will inherit the
|
||||||
|
file descriptor. */
|
||||||
|
pid_t child1 = xfork ();
|
||||||
|
TEST_VERIFY_EXIT (child1 >= 0);
|
||||||
|
if (child1 == 0)
|
||||||
|
_exit (0);
|
||||||
|
int child1_pidfd = pidfd_open (child1, 0);
|
||||||
|
TEST_VERIFY_EXIT (child1_pidfd != -1);
|
||||||
|
|
||||||
|
if (unshare (CLONE_NEWNS | CLONE_NEWUSER | CLONE_NEWPID) < 0)
|
||||||
|
{
|
||||||
|
/* Older kernels may not support all the options, or security
|
||||||
|
policy may block this call. */
|
||||||
|
if (errno == EINVAL || errno == EPERM || errno == ENOSPC)
|
||||||
|
exit (EXIT_UNSUPPORTED);
|
||||||
|
FAIL_EXIT1 ("unshare user/fs/pid failed: %m");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mount (NULL, "/", NULL, MS_REC | MS_PRIVATE, 0) != 0)
|
||||||
|
{
|
||||||
|
/* This happens if we're trying to create a nested container,
|
||||||
|
like if the build is running under podman, and we lack
|
||||||
|
priviledges. */
|
||||||
|
if (errno == EPERM)
|
||||||
|
_exit (EXIT_UNSUPPORTED);
|
||||||
|
else
|
||||||
|
_exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
pid_t child2 = xfork ();
|
||||||
|
if (child2 > 0)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
xwaitpid (child2, &status, 0);
|
||||||
|
TEST_VERIFY (WIFEXITED (status));
|
||||||
|
xwaitpid (child1, &status, 0);
|
||||||
|
TEST_VERIFY (WIFEXITED (status));
|
||||||
|
|
||||||
|
_exit (WEXITSTATUS (status));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now that we're pid 1 (effectively "root") we can mount /proc */
|
||||||
|
if (mount ("proc", "/proc", "proc", 0, NULL) != 0)
|
||||||
|
{
|
||||||
|
if (errno == EPERM)
|
||||||
|
_exit (EXIT_UNSUPPORTED);
|
||||||
|
else
|
||||||
|
_exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_COMPARE (pidfd_getpid (child1_pidfd), -1);
|
||||||
|
TEST_COMPARE (errno, EREMOTE);
|
||||||
|
|
||||||
|
_exit (EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
int child0_pidfd = pidfd_open (child0, 0);
|
||||||
|
TEST_VERIFY_EXIT (child0_pidfd != -1);
|
||||||
|
|
||||||
|
pid_t child0pid = pidfd_getpid (child0_pidfd);
|
||||||
|
|
||||||
|
siginfo_t info;
|
||||||
|
TEST_COMPARE (waitid (P_PIDFD, child0_pidfd, &info, WEXITED), 0);
|
||||||
|
if (info.si_status == EXIT_UNSUPPORTED)
|
||||||
|
FAIL_UNSUPPORTED ("unable to unshare user/fs/pid");
|
||||||
|
TEST_COMPARE (info.si_status, 0);
|
||||||
|
TEST_COMPARE (info.si_code, CLD_EXITED);
|
||||||
|
TEST_COMPARE (info.si_pid, child0pid);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <support/test-driver.c>
|
@ -2582,6 +2582,7 @@ GLIBC_2.38 strlcat F
|
|||||||
GLIBC_2.38 strlcpy F
|
GLIBC_2.38 strlcpy F
|
||||||
GLIBC_2.38 wcslcat F
|
GLIBC_2.38 wcslcat F
|
||||||
GLIBC_2.38 wcslcpy F
|
GLIBC_2.38 wcslcpy F
|
||||||
|
GLIBC_2.39 pidfd_getpid F
|
||||||
GLIBC_2.39 pidfd_spawn F
|
GLIBC_2.39 pidfd_spawn F
|
||||||
GLIBC_2.39 pidfd_spawnp F
|
GLIBC_2.39 pidfd_spawnp F
|
||||||
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
||||||
|
@ -2688,6 +2688,7 @@ GLIBC_2.38 strlcat F
|
|||||||
GLIBC_2.38 strlcpy F
|
GLIBC_2.38 strlcpy F
|
||||||
GLIBC_2.38 wcslcat F
|
GLIBC_2.38 wcslcat F
|
||||||
GLIBC_2.38 wcslcpy F
|
GLIBC_2.38 wcslcpy F
|
||||||
|
GLIBC_2.39 pidfd_getpid F
|
||||||
GLIBC_2.39 pidfd_spawn F
|
GLIBC_2.39 pidfd_spawn F
|
||||||
GLIBC_2.39 pidfd_spawnp F
|
GLIBC_2.39 pidfd_spawnp F
|
||||||
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
GLIBC_2.39 posix_spawnattr_getcgroup_np F
|
||||||
|
Loading…
Reference in New Issue
Block a user