From patchwork Fri Aug 18 14:06:42 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 1822937 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=l2I1nFYG; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4RS3cW1MVgz22PN for ; Sat, 19 Aug 2023 00:08:11 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 16D723882025 for ; Fri, 18 Aug 2023 14:08:09 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 16D723882025 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1692367689; bh=d7tsDNAYd+8bPWwNnFOQa/4ocgLJSV5H+wmUn9/O0wg=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=l2I1nFYG9ialkMdFfhoD2cygLluFOrp6cxSTRz02/BH6R5vRm5kgW6CKRpngRV2BH yeoEruu4yGDcVyvl37giQqgG3yQiGkNKT9IVFvjpCDFQj5QkyH+SLo5PsTZWRe7FFu rC0O2HYXlvd2mv1eIo7VT+Ps0DCTfE9bcBDvFnZk= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-oa1-x31.google.com (mail-oa1-x31.google.com [IPv6:2001:4860:4864:20::31]) by sourceware.org (Postfix) with ESMTPS id DA412383FDD5 for ; Fri, 18 Aug 2023 14:07:06 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org DA412383FDD5 Received: by mail-oa1-x31.google.com with SMTP id 586e51a60fabf-1c4cf775a14so475484fac.3 for ; Fri, 18 Aug 2023 07:07:06 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692367626; x=1692972426; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=d7tsDNAYd+8bPWwNnFOQa/4ocgLJSV5H+wmUn9/O0wg=; b=Tqt/XwBuW7L93t2mMnt0u/MGlWomiBj7wZk2hJbmHzFgEJKnnPK1lTsgFzdaip4lKr aKPVdRCPhp+C4yAXV2C3Pva7PHrrAYGp3UsPBXXkBHMKuvohk3kVJLEXl2rDphpnNa5F dk8VxFFG3gVS73eaJVAftin5tXlgOSKGFoTzFIlp/9fBChciVhyUdZi/EqY2HHRnu5qV 41yLRE+PWoMKhB9ecp1g1vGgWMKMgc7v9GZ6dMaCEOPr4EpK9Sl/RGEd5ZDoN2Wl+hrs gMM3d/JcK09QZmF8YXDX7HJNR82O0Mzh6bvmTamdOYeL9JaRy00uyg1LjjvDKAEFj5sr sqbQ== X-Gm-Message-State: AOJu0YzSocs5+Y7tO9F7ZNW2u8th3c3yo28QkVDBvTgVlYHBwWyL1Gme yznp7RcVPwQupDcVi1/0FKgZFCOe0BcsyFF737orpA== X-Google-Smtp-Source: AGHT+IGU2NR3rgAvXbP88Lr+neeSPeKNJx2GR7VgwjISegwdBoJ9h5MuI3irRl4ENmk0v7gjDmoMQQ== X-Received: by 2002:a05:6870:b295:b0:1bb:6cca:3468 with SMTP id c21-20020a056870b29500b001bb6cca3468mr3222592oao.47.1692367625184; Fri, 18 Aug 2023 07:07:05 -0700 (PDT) Received: from mandiga.. ([2804:1b3:a7c2:c275:7563:d0a5:7f5d:1313]) by smtp.gmail.com with ESMTPSA id r7-20020a056870734700b001c0e840ebcfsm1042841oal.35.2023.08.18.07.07.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 18 Aug 2023 07:07:04 -0700 (PDT) To: libc-alpha@sourceware.org, Florian Weimer Subject: [PATCH v8 7/7] linux: Add pidfd_getpid Date: Fri, 18 Aug 2023 11:06:42 -0300 Message-Id: <20230818140642.1623571-8-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230818140642.1623571-1-adhemerval.zanella@linaro.org> References: <20230818140642.1623571-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Netto Reply-To: Adhemerval Zanella Errors-To: libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org Sender: "Libc-alpha" 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 --- NEWS | 4 + manual/process.texi | 38 ++++++ sysdeps/unix/sysv/linux/Makefile | 3 + sysdeps/unix/sysv/linux/Versions | 1 + sysdeps/unix/sysv/linux/aarch64/libc.abilist | 1 + sysdeps/unix/sysv/linux/alpha/libc.abilist | 1 + sysdeps/unix/sysv/linux/arc/libc.abilist | 1 + sysdeps/unix/sysv/linux/arm/be/libc.abilist | 1 + sysdeps/unix/sysv/linux/arm/le/libc.abilist | 1 + sysdeps/unix/sysv/linux/clone-pidfd-support.c | 2 +- sysdeps/unix/sysv/linux/csky/libc.abilist | 1 + sysdeps/unix/sysv/linux/hppa/libc.abilist | 1 + sysdeps/unix/sysv/linux/i386/libc.abilist | 1 + sysdeps/unix/sysv/linux/ia64/libc.abilist | 1 + .../sysv/linux/loongarch/lp64/libc.abilist | 1 + .../sysv/linux/m68k/coldfire/libc.abilist | 1 + .../unix/sysv/linux/m68k/m680x0/libc.abilist | 1 + .../sysv/linux/microblaze/be/libc.abilist | 1 + .../sysv/linux/microblaze/le/libc.abilist | 1 + .../sysv/linux/mips/mips32/fpu/libc.abilist | 1 + .../sysv/linux/mips/mips32/nofpu/libc.abilist | 1 + .../sysv/linux/mips/mips64/n32/libc.abilist | 1 + .../sysv/linux/mips/mips64/n64/libc.abilist | 1 + sysdeps/unix/sysv/linux/nios2/libc.abilist | 1 + sysdeps/unix/sysv/linux/or1k/libc.abilist | 1 + sysdeps/unix/sysv/linux/pidfd_getpid.c | 126 ++++++++++++++++++ .../linux/powerpc/powerpc32/fpu/libc.abilist | 1 + .../powerpc/powerpc32/nofpu/libc.abilist | 1 + .../linux/powerpc/powerpc64/be/libc.abilist | 1 + .../linux/powerpc/powerpc64/le/libc.abilist | 1 + sysdeps/unix/sysv/linux/procutils.c | 97 ++++++++++++++ sysdeps/unix/sysv/linux/procutils.h | 43 ++++++ .../unix/sysv/linux/riscv/rv32/libc.abilist | 1 + .../unix/sysv/linux/riscv/rv64/libc.abilist | 1 + .../unix/sysv/linux/s390/s390-32/libc.abilist | 1 + .../unix/sysv/linux/s390/s390-64/libc.abilist | 1 + sysdeps/unix/sysv/linux/sh/be/libc.abilist | 1 + sysdeps/unix/sysv/linux/sh/le/libc.abilist | 1 + .../sysv/linux/sparc/sparc32/libc.abilist | 1 + .../sysv/linux/sparc/sparc64/libc.abilist | 1 + sysdeps/unix/sysv/linux/sys/pidfd.h | 4 + sysdeps/unix/sysv/linux/tst-pidfd.c | 48 +++++++ sysdeps/unix/sysv/linux/tst-pidfd_getpid.c | 126 ++++++++++++++++++ .../unix/sysv/linux/x86_64/64/libc.abilist | 1 + .../unix/sysv/linux/x86_64/x32/libc.abilist | 1 + 45 files changed, 525 insertions(+), 1 deletion(-) create mode 100644 sysdeps/unix/sysv/linux/pidfd_getpid.c create mode 100644 sysdeps/unix/sysv/linux/procutils.c create mode 100644 sysdeps/unix/sysv/linux/procutils.h create mode 100644 sysdeps/unix/sysv/linux/tst-pidfd_getpid.c diff --git a/NEWS b/NEWS index 00e9553e8f..45ccb2e64b 100644 --- a/NEWS +++ b/NEWS @@ -34,6 +34,10 @@ Major new features: posix_spawnattr_getcgroup_np), setting a different signal on process termination, and making the function act as _Fork. +* 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: [Add deprecations, removals and changes affecting compatibility here] diff --git a/manual/process.texi b/manual/process.texi index e6ac1f934f..1026b8d200 100644 --- a/manual/process.texi +++ b/manual/process.texi @@ -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 Identification:: How to get the process ID of a 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. * Process Completion:: How to tell when a child process has completed. * Process Completion Status:: How to interpret the status value @@ -424,6 +425,43 @@ child with @code{wait} or @code{waitid}. This function is a GNU extension and specific to Linux. @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 @section Executing a File @cindex executing a file diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index c9164e9d0a..2a8ab8b96b 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -213,6 +213,7 @@ tests += \ tst-ofdlocks \ tst-personality \ tst-pidfd \ + tst-pidfd_getpid \ tst-pkey \ tst-ppoll \ tst-prctl \ @@ -494,8 +495,10 @@ sysdep_routines += \ getcpu \ oldglob \ fork_np \ + pidfd_getpid \ pidfd_spawn \ pidfd_spawnp \ + procutils \ sched_getcpu \ spawnattr_getcgroup_np \ spawnattr_setcgroup_np \ diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions index c677631f24..ce3579e1c2 100644 --- a/sysdeps/unix/sysv/linux/Versions +++ b/sysdeps/unix/sysv/linux/Versions @@ -323,6 +323,7 @@ libc { } GLIBC_2.39 { fork_np; + pidfd_getpid; pidfd_spawn; pidfd_spawnp; posix_spawnattr_getcgroup_np; diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist index dab02f0087..7463a0e073 100644 --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist @@ -2674,6 +2674,7 @@ GLIBC_2.38 strlcpy F GLIBC_2.38 wcslcat F GLIBC_2.38 wcslcpy F GLIBC_2.39 fork_np F +GLIBC_2.39 pidfd_getpid F GLIBC_2.39 pidfd_spawn F GLIBC_2.39 pidfd_spawnp F GLIBC_2.39 posix_spawnattr_getcgroup_np F diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist index 1db00408cf..c708c87c78 100644 --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist @@ -2783,6 +2783,7 @@ GLIBC_2.38 strlcpy F GLIBC_2.38 wcslcat F GLIBC_2.38 wcslcpy F GLIBC_2.39 fork_np F +GLIBC_2.39 pidfd_getpid F GLIBC_2.39 pidfd_spawn F GLIBC_2.39 pidfd_spawnp F GLIBC_2.39 posix_spawnattr_getcgroup_np F diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist index 032aacc1ba..390fc7da90 100644 --- a/sysdeps/unix/sysv/linux/arc/libc.abilist +++ b/sysdeps/unix/sysv/linux/arc/libc.abilist @@ -2435,6 +2435,7 @@ GLIBC_2.38 strlcpy F GLIBC_2.38 wcslcat F GLIBC_2.38 wcslcpy F GLIBC_2.39 fork_np F +GLIBC_2.39 pidfd_getpid F GLIBC_2.39 pidfd_spawn F GLIBC_2.39 pidfd_spawnp F GLIBC_2.39 posix_spawnattr_getcgroup_np F diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist index 9f3ef16280..98971b6b4c 100644 --- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist @@ -555,6 +555,7 @@ GLIBC_2.38 strlcpy F GLIBC_2.38 wcslcat F GLIBC_2.38 wcslcpy F GLIBC_2.39 fork_np F +GLIBC_2.39 pidfd_getpid F GLIBC_2.39 pidfd_spawn F GLIBC_2.39 pidfd_spawnp F GLIBC_2.39 posix_spawnattr_getcgroup_np F diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist index c2c6c8af6b..2d1ae3768e 100644 --- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist @@ -552,6 +552,7 @@ GLIBC_2.38 strlcpy F GLIBC_2.38 wcslcat F GLIBC_2.38 wcslcpy F GLIBC_2.39 fork_np F +GLIBC_2.39 pidfd_getpid F GLIBC_2.39 pidfd_spawn F GLIBC_2.39 pidfd_spawnp F GLIBC_2.39 posix_spawnattr_getcgroup_np F diff --git a/sysdeps/unix/sysv/linux/clone-pidfd-support.c b/sysdeps/unix/sysv/linux/clone-pidfd-support.c index 4411e2b9ea..45378957b0 100644 --- a/sysdeps/unix/sysv/linux/clone-pidfd-support.c +++ b/sysdeps/unix/sysv/linux/clone-pidfd-support.c @@ -56,5 +56,5 @@ __clone_pidfd_supported (void) atomic_store_relaxed (&__waitid_pidfd_supported, state); } - return state > 1; + return state > 0; } diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist index 4112163af2..99ca4e06e9 100644 --- a/sysdeps/unix/sysv/linux/csky/libc.abilist +++ b/sysdeps/unix/sysv/linux/csky/libc.abilist @@ -2711,6 +2711,7 @@ GLIBC_2.38 strlcpy F GLIBC_2.38 wcslcat F GLIBC_2.38 wcslcpy F GLIBC_2.39 fork_np F +GLIBC_2.39 pidfd_getpid F GLIBC_2.39 pidfd_spawn F GLIBC_2.39 pidfd_spawnp F GLIBC_2.39 posix_spawnattr_getcgroup_np F diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist index b01734661b..718c3c5545 100644 --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist @@ -2660,6 +2660,7 @@ GLIBC_2.38 strlcpy F GLIBC_2.38 wcslcat F GLIBC_2.38 wcslcpy F GLIBC_2.39 fork_np F +GLIBC_2.39 pidfd_getpid F GLIBC_2.39 pidfd_spawn F GLIBC_2.39 pidfd_spawnp F GLIBC_2.39 posix_spawnattr_getcgroup_np F diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist index 14e58ef02d..2864b5b223 100644 --- a/sysdeps/unix/sysv/linux/i386/libc.abilist +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist @@ -2844,6 +2844,7 @@ GLIBC_2.38 strlcpy F GLIBC_2.38 wcslcat F GLIBC_2.38 wcslcpy F GLIBC_2.39 fork_np F +GLIBC_2.39 pidfd_getpid F GLIBC_2.39 pidfd_spawn F GLIBC_2.39 pidfd_spawnp F GLIBC_2.39 posix_spawnattr_getcgroup_np F diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist index 25936400b8..002f16a6cb 100644 --- a/sysdeps/unix/sysv/linux/ia64/libc.abilist +++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist @@ -2609,6 +2609,7 @@ GLIBC_2.38 strlcpy F GLIBC_2.38 wcslcat F GLIBC_2.38 wcslcpy F GLIBC_2.39 fork_np F +GLIBC_2.39 pidfd_getpid F GLIBC_2.39 pidfd_spawn F GLIBC_2.39 pidfd_spawnp F GLIBC_2.39 posix_spawnattr_getcgroup_np F diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist index 4299a45d2f..c799d98fca 100644 --- a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist +++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist @@ -2195,6 +2195,7 @@ GLIBC_2.38 strlcpy F GLIBC_2.38 wcslcat F GLIBC_2.38 wcslcpy F GLIBC_2.39 fork_np F +GLIBC_2.39 pidfd_getpid F GLIBC_2.39 pidfd_spawn F GLIBC_2.39 pidfd_spawnp F GLIBC_2.39 posix_spawnattr_getcgroup_np F diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist index 98d11f7e00..de1928d13f 100644 --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist @@ -556,6 +556,7 @@ GLIBC_2.38 strlcpy F GLIBC_2.38 wcslcat F GLIBC_2.38 wcslcpy F GLIBC_2.39 fork_np F +GLIBC_2.39 pidfd_getpid F GLIBC_2.39 pidfd_spawn F GLIBC_2.39 pidfd_spawnp F GLIBC_2.39 posix_spawnattr_getcgroup_np F diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist index 311b17c166..1f4c12e3fd 100644 --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist @@ -2787,6 +2787,7 @@ GLIBC_2.38 strlcpy F GLIBC_2.38 wcslcat F GLIBC_2.38 wcslcpy F GLIBC_2.39 fork_np F +GLIBC_2.39 pidfd_getpid F GLIBC_2.39 pidfd_spawn F GLIBC_2.39 pidfd_spawnp F GLIBC_2.39 posix_spawnattr_getcgroup_np F diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist index 9a645345e7..9d51eb1eb1 100644 --- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist @@ -2760,6 +2760,7 @@ GLIBC_2.38 strlcpy F GLIBC_2.38 wcslcat F GLIBC_2.38 wcslcpy F GLIBC_2.39 fork_np F +GLIBC_2.39 pidfd_getpid F GLIBC_2.39 pidfd_spawn F GLIBC_2.39 pidfd_spawnp F GLIBC_2.39 posix_spawnattr_getcgroup_np F diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist index bc6b3094fc..a5373cd308 100644 --- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist @@ -2757,6 +2757,7 @@ GLIBC_2.38 strlcpy F GLIBC_2.38 wcslcat F GLIBC_2.38 wcslcpy F GLIBC_2.39 fork_np F +GLIBC_2.39 pidfd_getpid F GLIBC_2.39 pidfd_spawn F GLIBC_2.39 pidfd_spawnp F GLIBC_2.39 posix_spawnattr_getcgroup_np F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist index 14f2335c29..f71d0447ba 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist @@ -2752,6 +2752,7 @@ GLIBC_2.38 strlcpy F GLIBC_2.38 wcslcat F GLIBC_2.38 wcslcpy F GLIBC_2.39 fork_np F +GLIBC_2.39 pidfd_getpid F GLIBC_2.39 pidfd_spawn F GLIBC_2.39 pidfd_spawnp F GLIBC_2.39 posix_spawnattr_getcgroup_np F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist index f41a1adaca..511a11f618 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist @@ -2750,6 +2750,7 @@ GLIBC_2.38 strlcpy F GLIBC_2.38 wcslcat F GLIBC_2.38 wcslcpy F GLIBC_2.39 fork_np F +GLIBC_2.39 pidfd_getpid F GLIBC_2.39 pidfd_spawn F GLIBC_2.39 pidfd_spawnp F GLIBC_2.39 posix_spawnattr_getcgroup_np F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist index 3500745aa0..e414749b65 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist @@ -2758,6 +2758,7 @@ GLIBC_2.38 strlcpy F GLIBC_2.38 wcslcat F GLIBC_2.38 wcslcpy F GLIBC_2.39 fork_np F +GLIBC_2.39 pidfd_getpid F GLIBC_2.39 pidfd_spawn F GLIBC_2.39 pidfd_spawnp F GLIBC_2.39 posix_spawnattr_getcgroup_np F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist index 64cc996c51..2e5ebb90ac 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist @@ -2660,6 +2660,7 @@ GLIBC_2.38 strlcpy F GLIBC_2.38 wcslcat F GLIBC_2.38 wcslcpy F GLIBC_2.39 fork_np F +GLIBC_2.39 pidfd_getpid F GLIBC_2.39 pidfd_spawn F GLIBC_2.39 pidfd_spawnp F GLIBC_2.39 posix_spawnattr_getcgroup_np F diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist index 723956e4be..c8c2f8b5c3 100644 --- a/sysdeps/unix/sysv/linux/nios2/libc.abilist +++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist @@ -2799,6 +2799,7 @@ GLIBC_2.38 strlcpy F GLIBC_2.38 wcslcat F GLIBC_2.38 wcslcpy F GLIBC_2.39 fork_np F +GLIBC_2.39 pidfd_getpid F GLIBC_2.39 pidfd_spawn F GLIBC_2.39 pidfd_spawnp F GLIBC_2.39 posix_spawnattr_getcgroup_np F diff --git a/sysdeps/unix/sysv/linux/or1k/libc.abilist b/sysdeps/unix/sysv/linux/or1k/libc.abilist index 97657be343..a50a669712 100644 --- a/sysdeps/unix/sysv/linux/or1k/libc.abilist +++ b/sysdeps/unix/sysv/linux/or1k/libc.abilist @@ -2181,6 +2181,7 @@ GLIBC_2.38 strlcpy F GLIBC_2.38 wcslcat F GLIBC_2.38 wcslcpy F GLIBC_2.39 fork_np F +GLIBC_2.39 pidfd_getpid F GLIBC_2.39 pidfd_spawn F GLIBC_2.39 pidfd_spawnp F GLIBC_2.39 posix_spawnattr_getcgroup_np F diff --git a/sysdeps/unix/sysv/linux/pidfd_getpid.c b/sysdeps/unix/sysv/linux/pidfd_getpid.c new file mode 100644 index 0000000000..d03936e97f --- /dev/null +++ b/sysdeps/unix/sysv/linux/pidfd_getpid.c @@ -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 + . */ + +#include <_itoa.h> +#include +#include +#include +#include +#include +#include +#include + +#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; +} diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist index a3fa2f4f87..becd490bef 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist @@ -2826,6 +2826,7 @@ GLIBC_2.38 strlcpy F GLIBC_2.38 wcslcat F GLIBC_2.38 wcslcpy F GLIBC_2.39 fork_np F +GLIBC_2.39 pidfd_getpid F GLIBC_2.39 pidfd_spawn F GLIBC_2.39 pidfd_spawnp F GLIBC_2.39 posix_spawnattr_getcgroup_np F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist index bddf0f2d01..cc088490ae 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist @@ -2859,6 +2859,7 @@ GLIBC_2.38 strlcpy F GLIBC_2.38 wcslcat F GLIBC_2.38 wcslcpy F GLIBC_2.39 fork_np F +GLIBC_2.39 pidfd_getpid F GLIBC_2.39 pidfd_spawn F GLIBC_2.39 pidfd_spawnp F GLIBC_2.39 posix_spawnattr_getcgroup_np F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist index ee9db4eff2..70872b29c5 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist @@ -2580,6 +2580,7 @@ GLIBC_2.38 strlcpy F GLIBC_2.38 wcslcat F GLIBC_2.38 wcslcpy F GLIBC_2.39 fork_np F +GLIBC_2.39 pidfd_getpid F GLIBC_2.39 pidfd_spawn F GLIBC_2.39 pidfd_spawnp F GLIBC_2.39 posix_spawnattr_getcgroup_np F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist index 0a0c4c4650..e2c7190ccb 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist @@ -2894,6 +2894,7 @@ GLIBC_2.38 strlcpy F GLIBC_2.38 wcslcat F GLIBC_2.38 wcslcpy F GLIBC_2.39 fork_np F +GLIBC_2.39 pidfd_getpid F GLIBC_2.39 pidfd_spawn F GLIBC_2.39 pidfd_spawnp F GLIBC_2.39 posix_spawnattr_getcgroup_np F diff --git a/sysdeps/unix/sysv/linux/procutils.c b/sysdeps/unix/sysv/linux/procutils.c new file mode 100644 index 0000000000..30fc3a063a --- /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 + . */ + +#include +#include +#include +#include + +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; +} diff --git a/sysdeps/unix/sysv/linux/procutils.h b/sysdeps/unix/sysv/linux/procutils.h new file mode 100644 index 0000000000..b3c2f6fb55 --- /dev/null +++ b/sysdeps/unix/sysv/linux/procutils.h @@ -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 + . */ + +#ifndef _PROCUTILS_H +#define _PROCUTILS_H + +#include + +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 diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist index 0c9a1648e1..01b72f4a64 100644 --- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist +++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist @@ -2437,6 +2437,7 @@ GLIBC_2.38 strlcpy F GLIBC_2.38 wcslcat F GLIBC_2.38 wcslcpy F GLIBC_2.39 fork_np F +GLIBC_2.39 pidfd_getpid F GLIBC_2.39 pidfd_spawn F GLIBC_2.39 pidfd_spawnp F GLIBC_2.39 posix_spawnattr_getcgroup_np F diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist index 0acdd6fff4..8cfa87668c 100644 --- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist @@ -2637,6 +2637,7 @@ GLIBC_2.38 strlcpy F GLIBC_2.38 wcslcat F GLIBC_2.38 wcslcpy F GLIBC_2.39 fork_np F +GLIBC_2.39 pidfd_getpid F GLIBC_2.39 pidfd_spawn F GLIBC_2.39 pidfd_spawnp F GLIBC_2.39 posix_spawnattr_getcgroup_np F diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist index b94792e4c1..3174961090 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist @@ -2824,6 +2824,7 @@ GLIBC_2.38 strlcpy F GLIBC_2.38 wcslcat F GLIBC_2.38 wcslcpy F GLIBC_2.39 fork_np F +GLIBC_2.39 pidfd_getpid F GLIBC_2.39 pidfd_spawn F GLIBC_2.39 pidfd_spawnp F GLIBC_2.39 posix_spawnattr_getcgroup_np F diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist index 7d3a6e3c90..da6ec4a3c1 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist @@ -2617,6 +2617,7 @@ GLIBC_2.38 strlcpy F GLIBC_2.38 wcslcat F GLIBC_2.38 wcslcpy F GLIBC_2.39 fork_np F +GLIBC_2.39 pidfd_getpid F GLIBC_2.39 pidfd_spawn F GLIBC_2.39 pidfd_spawnp F GLIBC_2.39 posix_spawnattr_getcgroup_np F diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist index 1c26740359..8a3fd3b4c7 100644 --- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist @@ -2667,6 +2667,7 @@ GLIBC_2.38 strlcpy F GLIBC_2.38 wcslcat F GLIBC_2.38 wcslcpy F GLIBC_2.39 fork_np F +GLIBC_2.39 pidfd_getpid F GLIBC_2.39 pidfd_spawn F GLIBC_2.39 pidfd_spawnp F GLIBC_2.39 posix_spawnattr_getcgroup_np F diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist index 5b0bd8c6c8..30346fae9e 100644 --- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist @@ -2664,6 +2664,7 @@ GLIBC_2.38 strlcpy F GLIBC_2.38 wcslcat F GLIBC_2.38 wcslcpy F GLIBC_2.39 fork_np F +GLIBC_2.39 pidfd_getpid F GLIBC_2.39 pidfd_spawn F GLIBC_2.39 pidfd_spawnp F GLIBC_2.39 posix_spawnattr_getcgroup_np F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist index 9e18f09c1e..d9f40c1f5e 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist @@ -2819,6 +2819,7 @@ GLIBC_2.38 strlcpy F GLIBC_2.38 wcslcat F GLIBC_2.38 wcslcpy F GLIBC_2.39 fork_np F +GLIBC_2.39 pidfd_getpid F GLIBC_2.39 pidfd_spawn F GLIBC_2.39 pidfd_spawnp F GLIBC_2.39 posix_spawnattr_getcgroup_np F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist index 3a94cf17ee..162027b16f 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist @@ -2632,6 +2632,7 @@ GLIBC_2.38 strlcpy F GLIBC_2.38 wcslcat F GLIBC_2.38 wcslcpy F GLIBC_2.39 fork_np F +GLIBC_2.39 pidfd_getpid F GLIBC_2.39 pidfd_spawn F GLIBC_2.39 pidfd_spawnp F GLIBC_2.39 posix_spawnattr_getcgroup_np F diff --git a/sysdeps/unix/sysv/linux/sys/pidfd.h b/sysdeps/unix/sysv/linux/sys/pidfd.h index 342e593288..5179e2e795 100644 --- a/sysdeps/unix/sysv/linux/sys/pidfd.h +++ b/sysdeps/unix/sysv/linux/sys/pidfd.h @@ -46,4 +46,8 @@ extern int pidfd_getfd (int __pidfd, int __targetfd, extern int pidfd_send_signal (int __pidfd, int __sig, siginfo_t *__info, 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 */ diff --git a/sysdeps/unix/sysv/linux/tst-pidfd.c b/sysdeps/unix/sysv/linux/tst-pidfd.c index 64d8a2ef40..b254020175 100644 --- a/sysdeps/unix/sysv/linux/tst-pidfd.c +++ b/sysdeps/unix/sysv/linux/tst-pidfd.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -27,6 +28,8 @@ #include #include #include +#include +#include #define REMOTE_PATH "/dev/null" @@ -102,6 +105,45 @@ do_test (void) ppid = getpid (); 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. */ + { + fork_np_args_t args = { + .fork_np_flags = FORK_NP_PIDFD, + }; + pid_t pidfork = fork_np (&args, sizeof args); + if (pidfork == 0) + _exit (EXIT_SUCCESS); + + /* 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 (args.fork_np_pidfd); + if (pid > 0) + support_process_state_wait (pid, support_process_state_zombie); + + siginfo_t info; + TEST_COMPARE (waitid (P_PIDFD, args.fork_np_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 (args.fork_np_pidfd); + TEST_COMPARE (pid, -1); + TEST_COMPARE (errno, ESRCH); + + xclose (args.fork_np_pidfd); + } + TEST_COMPARE (socketpair (AF_UNIX, SOCK_STREAM, 0, sockets), 0); pid_t pid = xfork (); @@ -118,6 +160,12 @@ do_test (void) int pidfd = pidfd_open (pid, 0); 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. */ support_process_state_wait (pid, support_process_state_sleeping); TEST_COMPARE (pidfd_send_signal (pidfd, SIGUSR1, NULL, 0), 0); diff --git a/sysdeps/unix/sysv/linux/tst-pidfd_getpid.c b/sysdeps/unix/sysv/linux/tst-pidfd_getpid.c new file mode 100644 index 0000000000..fe418465c7 --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-pidfd_getpid.c @@ -0,0 +1,126 @@ +/* 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 + . */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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. */ + { + fork_np_args_t child_args = { + .fork_np_flags = FORK_NP_PIDFD, + }; + pid_t child0 = fork_np (&child_args, sizeof child_args); + TEST_VERIFY_EXIT (child0 >= 0); + if (child0 == 0) + { + /* Create another unrelated descriptor, so child2 will inherit the + file descriptor. */ + fork_np_args_t subchild_args = { + .fork_np_flags = FORK_NP_PIDFD, + }; + pid_t child1 = fork_np (&subchild_args, sizeof subchild_args); + TEST_VERIFY_EXIT (child1 >= 0); + if (child1 == 0) + _exit (0); + + 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 (subchild_args.fork_np_pidfd), -1); + TEST_COMPARE (errno, EREMOTE); + + _exit (EXIT_SUCCESS); + } + + pid_t child0pid = pidfd_getpid (child_args.fork_np_pidfd); + + siginfo_t info; + TEST_COMPARE (waitid (P_PIDFD, child_args.fork_np_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 diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist index bf06381f82..f1e4f83345 100644 --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist @@ -2583,6 +2583,7 @@ GLIBC_2.38 strlcpy F GLIBC_2.38 wcslcat F GLIBC_2.38 wcslcpy F GLIBC_2.39 fork_np F +GLIBC_2.39 pidfd_getpid F GLIBC_2.39 pidfd_spawn F GLIBC_2.39 pidfd_spawnp F GLIBC_2.39 posix_spawnattr_getcgroup_np F diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist index 032347e89c..280bca96f3 100644 --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist @@ -2689,6 +2689,7 @@ GLIBC_2.38 strlcpy F GLIBC_2.38 wcslcat F GLIBC_2.38 wcslcpy F GLIBC_2.39 fork_np F +GLIBC_2.39 pidfd_getpid F GLIBC_2.39 pidfd_spawn F GLIBC_2.39 pidfd_spawnp F GLIBC_2.39 posix_spawnattr_getcgroup_np F