From patchwork Tue May 16 11:46:12 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: 69466 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 58B1D3856DCD for ; Tue, 16 May 2023 11:47:47 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 58B1D3856DCD DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1684237667; bh=jEkyITTypOB8y3pL7XGXLqUc2DOwLGu0mR6q/3mdpJ8=; 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=sS/BbkXxDr5DbXlqFlfSyuSuxneBYugnx1ok354dgYeEory/5OmM/NlOH8cqRh0l8 fRbe8PnpCueVs9OFDnh4/heYuw2w/Cixdl1gKYMZ8x66WBWnsoGFkpa+zosUDexx/t JO/1BGS345BNmrgZxO6PtqPD99Rqg0ZIrhhEqRH8= 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 6B22F3857000 for ; Tue, 16 May 2023 11:46:28 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 6B22F3857000 Received: by mail-oa1-x31.google.com with SMTP id 586e51a60fabf-1929818d7faso4039059fac.0 for ; Tue, 16 May 2023 04:46:28 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1684237587; x=1686829587; 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=jEkyITTypOB8y3pL7XGXLqUc2DOwLGu0mR6q/3mdpJ8=; b=Cke1UZXG4FvJaxF08xKxW5TVFOuj2t88nJ8BRztbTaGglc7TOgAOI40aW8ycWmW1MT 4l+CWwBN1dH02/Y0LIZYopJ7ddEQFshXiXAMRh7Otz1ecNY65CK0ZvfjrBVXFv1BL2lz De4Qj0RnLmnh53dckrH6eiK/wg1g9CVTuNdYIThMBWD75z/+Jhm7vPhcf3TIVQJ561dd pM+e5qd4tV3yE5k91voAq7KMavbFHBBhARHNgZSYddicybckJAO0wIxjUUKVrSs5H5Mp n44XzAsWAQUZliy4Q1c2RovQiJvkjnkpoOLGE/lg6Lpq0/xzOCuKaxwkZr3n/Y5W/xPt 6gzg== X-Gm-Message-State: AC+VfDyXgNgYZotX2FYAhqkW/sGIIWeHI3Kmn7FNjVCur2MEZhd5u8Pi PVwlCR7MaQT4X0Rde+j8FNAFoAeAbFJF7InC2IPamA== X-Google-Smtp-Source: ACHHUZ7H1Lr1eF+JUYcCpGWuWGTy//iEGPhA2CsVzyrt9Ok0XTEmpxuTmDUf1UxDMuSyWq09UIZVhA== X-Received: by 2002:a05:6870:82a3:b0:196:8e0e:abf6 with SMTP id q35-20020a05687082a300b001968e0eabf6mr7985968oae.21.1684237586495; Tue, 16 May 2023 04:46:26 -0700 (PDT) Received: from mandiga.. ([2804:1b3:a7c0:c914:8d13:db67:8de3:f7b]) by smtp.gmail.com with ESMTPSA id ea20-20020a056870071400b001964dc3dadesm6847311oab.45.2023.05.16.04.46.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 16 May 2023 04:46:25 -0700 (PDT) To: libc-alpha@sourceware.org, Luca Boccassi , Florian Weimer , Philip Withnall Subject: [PATCH v3 3/3] linux: Add pidfd_getpid Date: Tue, 16 May 2023 08:46:12 -0300 Message-Id: <20230516114612.159103-4-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230516114612.159103-1-adhemerval.zanella@linaro.org> References: <20230516114612.159103-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.5 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, T_SCC_BODY_TEXT_LINE 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+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" This interface allows to obtain the associated pid 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 set the errno accordingly. The possible errno values are the smae from open, read, and close (used on procps parsing), along with: - EINVAL if the FP is negative (similar to fexecve). - EBADF if the FD does not have a PID associated of if the fdinfo fields contains 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_PID or waitid support), Linux 5.15 (only clone support), and Linux 5.19 (full support including clone3). --- NEWS | 4 + manual/process.texi | 32 ++++ 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/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 | 94 ++++++++++ .../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 | 104 ++++++++++ sysdeps/unix/sysv/linux/procutils.h | 35 ++++ .../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 | 45 +++++ sysdeps/unix/sysv/linux/tst-pidfd_getpid.c | 177 ++++++++++++++++++ .../unix/sysv/linux/x86_64/64/libc.abilist | 1 + .../unix/sysv/linux/x86_64/x32/libc.abilist | 1 + 44 files changed, 533 insertions(+) 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 aaecdc1c5b..7334bb49e9 100644 --- a/NEWS +++ b/NEWS @@ -47,6 +47,10 @@ Major new features: return a process ID, it returns a file descriptor that can be used along other pidfd functions. +* On Linux, the pidfd_getpid has been added. It allows to retrieve the + process ID associated with process file descriptor created with + pid_spawn, pidfd_fork, or pidfd_open. + Deprecated and removed features, and other changes affecting compatibility: * In the Linux kernel for the hppa/parisc architecture some of the diff --git a/manual/process.texi b/manual/process.texi index 93e0ab5fb7..25417dce0d 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 @@ -389,6 +390,37 @@ Acts as @code{_Fork}, where it does not invoke any callbacks registered with This function is specific to Linux. +@node Querying a Process +@section Querying a Process + +The @code{pidfd_fork} function returned file descriptor can be used to query +for 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} 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 a value of @code{-1} and the +following @code{errno} error conditionas are defined: + +@table @code +@item EINVAL +The input file descriptor is negative. +@item EBADF +The input file descriptor 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. +@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 8673b6e437..52e277f8c0 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -210,6 +210,7 @@ tests += \ tst-ofdlocks \ tst-personality \ tst-pidfd \ + tst-pidfd_getpid \ tst-pkey \ tst-ppoll \ tst-prctl \ @@ -489,8 +490,10 @@ sysdep_routines += \ getcpu \ oldglob \ pidfd_fork \ + pidfd_getpid \ pidfd_spawn \ pidfd_spawnp \ + procutils \ sched_getcpu \ sched_getcpu \ # sysdep_routines diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions index 7e4109e9c5..047bc0c92a 100644 --- a/sysdeps/unix/sysv/linux/Versions +++ b/sysdeps/unix/sysv/linux/Versions @@ -323,6 +323,7 @@ libc { } GLIBC_2.38 { pidfd_fork; + pidfd_getpid; pidfd_spawn; pidfd_spawnp; } diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist index dbf7c44319..febfc78f29 100644 --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist @@ -2666,5 +2666,6 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 pidfd_fork F +GLIBC_2.38 pidfd_getpid F GLIBC_2.38 pidfd_spawn F GLIBC_2.38 pidfd_spawnp F diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist index a9d6ffce14..87f93beeb8 100644 --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist @@ -2775,6 +2775,7 @@ GLIBC_2.38 __nldbl___isoc23_vswscanf F GLIBC_2.38 __nldbl___isoc23_vwscanf F GLIBC_2.38 __nldbl___isoc23_wscanf F GLIBC_2.38 pidfd_fork F +GLIBC_2.38 pidfd_getpid F GLIBC_2.38 pidfd_spawn F GLIBC_2.38 pidfd_spawnp F GLIBC_2.4 _IO_fprintf F diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist index c08d548556..dd33567a75 100644 --- a/sysdeps/unix/sysv/linux/arc/libc.abilist +++ b/sysdeps/unix/sysv/linux/arc/libc.abilist @@ -2427,5 +2427,6 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 pidfd_fork F +GLIBC_2.38 pidfd_getpid F GLIBC_2.38 pidfd_spawn F GLIBC_2.38 pidfd_spawnp F diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist index f348336ee7..2344b8ae48 100644 --- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist @@ -547,6 +547,7 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 pidfd_fork F +GLIBC_2.38 pidfd_getpid F GLIBC_2.38 pidfd_spawn F GLIBC_2.38 pidfd_spawnp F GLIBC_2.4 _Exit F diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist index 5aed593521..b34ec3e9cc 100644 --- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist @@ -544,6 +544,7 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 pidfd_fork F +GLIBC_2.38 pidfd_getpid F GLIBC_2.38 pidfd_spawn F GLIBC_2.38 pidfd_spawnp F GLIBC_2.4 _Exit F diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist index 8a7022aaa8..f59d84fdb0 100644 --- a/sysdeps/unix/sysv/linux/csky/libc.abilist +++ b/sysdeps/unix/sysv/linux/csky/libc.abilist @@ -2703,5 +2703,6 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 pidfd_fork F +GLIBC_2.38 pidfd_getpid F GLIBC_2.38 pidfd_spawn F GLIBC_2.38 pidfd_spawnp F diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist index e2ac6949df..f6527bb9db 100644 --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist @@ -2652,6 +2652,7 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 pidfd_fork F +GLIBC_2.38 pidfd_getpid F GLIBC_2.38 pidfd_spawn F GLIBC_2.38 pidfd_spawnp F GLIBC_2.4 __confstr_chk F diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist index 5e8d49fc1f..28ccb54206 100644 --- a/sysdeps/unix/sysv/linux/i386/libc.abilist +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist @@ -2836,6 +2836,7 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 pidfd_fork F +GLIBC_2.38 pidfd_getpid F GLIBC_2.38 pidfd_spawn F GLIBC_2.38 pidfd_spawnp F GLIBC_2.4 __confstr_chk F diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist index 3cd3c80334..aabf217819 100644 --- a/sysdeps/unix/sysv/linux/ia64/libc.abilist +++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist @@ -2601,6 +2601,7 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 pidfd_fork F +GLIBC_2.38 pidfd_getpid F GLIBC_2.38 pidfd_spawn F GLIBC_2.38 pidfd_spawnp F GLIBC_2.4 __confstr_chk F diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist index 0965db2ff0..8b53d82e8c 100644 --- a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist +++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist @@ -2187,5 +2187,6 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 pidfd_fork F +GLIBC_2.38 pidfd_getpid F GLIBC_2.38 pidfd_spawn F GLIBC_2.38 pidfd_spawnp F diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist index 1ec24886a3..66bf4532ab 100644 --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist @@ -548,6 +548,7 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 pidfd_fork F +GLIBC_2.38 pidfd_getpid F GLIBC_2.38 pidfd_spawn F GLIBC_2.38 pidfd_spawnp F GLIBC_2.4 _Exit F diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist index 239b1d70be..0ee9fef825 100644 --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist @@ -2779,6 +2779,7 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 pidfd_fork F +GLIBC_2.38 pidfd_getpid F GLIBC_2.38 pidfd_spawn F GLIBC_2.38 pidfd_spawnp F GLIBC_2.4 __confstr_chk F diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist index dd41d63394..8861ebb4ca 100644 --- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist @@ -2752,5 +2752,6 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 pidfd_fork F +GLIBC_2.38 pidfd_getpid F GLIBC_2.38 pidfd_spawn F GLIBC_2.38 pidfd_spawnp F diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist index 55c3dcd471..008dda3746 100644 --- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist @@ -2749,5 +2749,6 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 pidfd_fork F +GLIBC_2.38 pidfd_getpid F GLIBC_2.38 pidfd_spawn F GLIBC_2.38 pidfd_spawnp F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist index 295e4d8608..2d0af493ed 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist @@ -2744,6 +2744,7 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 pidfd_fork F +GLIBC_2.38 pidfd_getpid F GLIBC_2.38 pidfd_spawn F GLIBC_2.38 pidfd_spawnp F GLIBC_2.4 __confstr_chk F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist index 19fb1aebe7..ae82d18edb 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist @@ -2742,6 +2742,7 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 pidfd_fork F +GLIBC_2.38 pidfd_getpid F GLIBC_2.38 pidfd_spawn F GLIBC_2.38 pidfd_spawnp F GLIBC_2.4 __confstr_chk F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist index 2dd6ef5416..87aee7f86d 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist @@ -2750,6 +2750,7 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 pidfd_fork F +GLIBC_2.38 pidfd_getpid F GLIBC_2.38 pidfd_spawn F GLIBC_2.38 pidfd_spawnp F GLIBC_2.4 __confstr_chk F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist index 6445d27220..c0d1fd370a 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist @@ -2652,6 +2652,7 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 pidfd_fork F +GLIBC_2.38 pidfd_getpid F GLIBC_2.38 pidfd_spawn F GLIBC_2.38 pidfd_spawnp F GLIBC_2.4 __confstr_chk F diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist index c1cc5134c9..06092621b9 100644 --- a/sysdeps/unix/sysv/linux/nios2/libc.abilist +++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist @@ -2791,5 +2791,6 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 pidfd_fork F +GLIBC_2.38 pidfd_getpid F GLIBC_2.38 pidfd_spawn F GLIBC_2.38 pidfd_spawnp F diff --git a/sysdeps/unix/sysv/linux/or1k/libc.abilist b/sysdeps/unix/sysv/linux/or1k/libc.abilist index 293643346a..88dcdd8b98 100644 --- a/sysdeps/unix/sysv/linux/or1k/libc.abilist +++ b/sysdeps/unix/sysv/linux/or1k/libc.abilist @@ -2173,5 +2173,6 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 pidfd_fork F +GLIBC_2.38 pidfd_getpid F GLIBC_2.38 pidfd_spawn F GLIBC_2.38 pidfd_spawnp 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..8650f60586 --- /dev/null +++ b/sysdeps/unix/sysv/linux/pidfd_getpid.c @@ -0,0 +1,94 @@ +/* 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; +}; + +static int +parse_fdinfo (const char *l, void *arg) +{ + enum { fieldlen = sizeof ("Pid:") - 1 }; + if (strncmp (l, "Pid:", fieldlen) != 0) + return 0; + + l += fieldlen; + + char *endp; + unsigned long n = strtoul (l, &endp, 10); + if (l == endp || (n > INT_MAX && n != ULONG_MAX)) + return 0; + + struct parse_fdinfo_t *fdinfo = arg; + fdinfo->found = true; + fdinfo->pid = n; + + return 1; +} + +pid_t +pidfd_getpid (int fd) +{ + if (__glibc_unlikely (fd < 0)) + { + __set_errno (EINVAL); + 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) == -1) + /* 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 03a35e860d..ce885f9136 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist @@ -2818,6 +2818,7 @@ GLIBC_2.38 __nldbl___isoc23_vswscanf F GLIBC_2.38 __nldbl___isoc23_vwscanf F GLIBC_2.38 __nldbl___isoc23_wscanf F GLIBC_2.38 pidfd_fork F +GLIBC_2.38 pidfd_getpid F GLIBC_2.38 pidfd_spawn F GLIBC_2.38 pidfd_spawnp F GLIBC_2.4 _IO_fprintf F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist index a91af4245b..8063a0606e 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist @@ -2851,6 +2851,7 @@ GLIBC_2.38 __nldbl___isoc23_vswscanf F GLIBC_2.38 __nldbl___isoc23_vwscanf F GLIBC_2.38 __nldbl___isoc23_wscanf F GLIBC_2.38 pidfd_fork F +GLIBC_2.38 pidfd_getpid F GLIBC_2.38 pidfd_spawn F GLIBC_2.38 pidfd_spawnp F GLIBC_2.4 _IO_fprintf F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist index c15137b9ad..21fb95a352 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist @@ -2572,6 +2572,7 @@ GLIBC_2.38 __nldbl___isoc23_vswscanf F GLIBC_2.38 __nldbl___isoc23_vwscanf F GLIBC_2.38 __nldbl___isoc23_wscanf F GLIBC_2.38 pidfd_fork F +GLIBC_2.38 pidfd_getpid F GLIBC_2.38 pidfd_spawn F GLIBC_2.38 pidfd_spawnp F GLIBC_2.4 _IO_fprintf F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist index 12c0f4cfba..14bda5b5b8 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist @@ -2886,5 +2886,6 @@ GLIBC_2.38 __nldbl___isoc23_vswscanf F GLIBC_2.38 __nldbl___isoc23_vwscanf F GLIBC_2.38 __nldbl___isoc23_wscanf F GLIBC_2.38 pidfd_fork F +GLIBC_2.38 pidfd_getpid F GLIBC_2.38 pidfd_spawn F GLIBC_2.38 pidfd_spawnp F diff --git a/sysdeps/unix/sysv/linux/procutils.c b/sysdeps/unix/sysv/linux/procutils.c new file mode 100644 index 0000000000..83b327cb9a --- /dev/null +++ b/sysdeps/unix/sysv/linux/procutils.c @@ -0,0 +1,104 @@ +/* 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 = __read_nocancel (fd, *re, buffer_end - *re); + if (n < 0) + return -1; + + *re += n; + + nl = memchr (*cp, '\n', *re - *cp); + while (nl == NULL && *re == buffer_end) + { + /* Truncate too long lines. */ + *re = buffer + 3 * (buffer_end - buffer) / 4; + n = __read_nocancel (fd, *re, buffer_end - *re); + if (n < 0) + return -1; + + nl = memchr (*re, '\n', n); + **re = '\0'; + *re += n; + } + } + 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; +} + +int +procutils_read_file (const char *filename, procutils_closure_t closure, + void *arg) +{ + enum { buffer_size = 1024 }; + char buffer[buffer_size]; + char *buffer_end = buffer + buffer_size; + char *cp = buffer_end; + char *re = buffer_end; + + int fd = __open64_nocancel (filename, O_RDONLY | O_CLOEXEC); + if (fd == -1) + return -1; + + 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; +} diff --git a/sysdeps/unix/sysv/linux/procutils.h b/sysdeps/unix/sysv/linux/procutils.h new file mode 100644 index 0000000000..64e1080920 --- /dev/null +++ b/sysdeps/unix/sysv/linux/procutils.h @@ -0,0 +1,35 @@ +/* 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 + +typedef int (*procutils_closure_t)(const char *line, void *arg); + +/* 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 true if the read should continue, or false + if the function should stop. + + It returns 0 in case of success, or -1 otherwise. */ +int 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 9537dac42d..b294ec1021 100644 --- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist +++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist @@ -2429,5 +2429,6 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 pidfd_fork F +GLIBC_2.38 pidfd_getpid F GLIBC_2.38 pidfd_spawn F GLIBC_2.38 pidfd_spawnp F diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist index ea72e6b648..61921a02d4 100644 --- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist @@ -2629,5 +2629,6 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 pidfd_fork F +GLIBC_2.38 pidfd_getpid F GLIBC_2.38 pidfd_spawn F GLIBC_2.38 pidfd_spawnp F diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist index d6c895b487..fbc2d5826f 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist @@ -2816,6 +2816,7 @@ GLIBC_2.38 __nldbl___isoc23_vswscanf F GLIBC_2.38 __nldbl___isoc23_vwscanf F GLIBC_2.38 __nldbl___isoc23_wscanf F GLIBC_2.38 pidfd_fork F +GLIBC_2.38 pidfd_getpid F GLIBC_2.38 pidfd_spawn F GLIBC_2.38 pidfd_spawnp F GLIBC_2.4 _IO_fprintf F diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist index b375f5a7ab..45ab26d7a7 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist @@ -2609,6 +2609,7 @@ GLIBC_2.38 __nldbl___isoc23_vswscanf F GLIBC_2.38 __nldbl___isoc23_vwscanf F GLIBC_2.38 __nldbl___isoc23_wscanf F GLIBC_2.38 pidfd_fork F +GLIBC_2.38 pidfd_getpid F GLIBC_2.38 pidfd_spawn F GLIBC_2.38 pidfd_spawnp F GLIBC_2.4 _IO_fprintf F diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist index 7b2266ecb3..8de69e0057 100644 --- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist @@ -2659,6 +2659,7 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 pidfd_fork F +GLIBC_2.38 pidfd_getpid F GLIBC_2.38 pidfd_spawn F GLIBC_2.38 pidfd_spawnp F GLIBC_2.4 __confstr_chk F diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist index 2f9f732044..3821ce3676 100644 --- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist @@ -2656,6 +2656,7 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 pidfd_fork F +GLIBC_2.38 pidfd_getpid F GLIBC_2.38 pidfd_spawn F GLIBC_2.38 pidfd_spawnp F GLIBC_2.4 __confstr_chk F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist index 144d54ebf2..7be5b0c125 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist @@ -2811,6 +2811,7 @@ GLIBC_2.38 __nldbl___isoc23_vswscanf F GLIBC_2.38 __nldbl___isoc23_vwscanf F GLIBC_2.38 __nldbl___isoc23_wscanf F GLIBC_2.38 pidfd_fork F +GLIBC_2.38 pidfd_getpid F GLIBC_2.38 pidfd_spawn F GLIBC_2.38 pidfd_spawnp F GLIBC_2.4 _IO_fprintf F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist index bc8bd8ff54..a09b2efc90 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist @@ -2624,6 +2624,7 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 pidfd_fork F +GLIBC_2.38 pidfd_getpid F GLIBC_2.38 pidfd_spawn F GLIBC_2.38 pidfd_spawnp F GLIBC_2.4 __confstr_chk F diff --git a/sysdeps/unix/sysv/linux/sys/pidfd.h b/sysdeps/unix/sysv/linux/sys/pidfd.h index 1942773957..5be3eb1167 100644 --- a/sysdeps/unix/sysv/linux/sys/pidfd.h +++ b/sysdeps/unix/sysv/linux/sys/pidfd.h @@ -59,4 +59,8 @@ extern int pidfd_send_signal (int __pidfd, int __sig, siginfo_t *__info, of the new process to the parent process. */ extern int pidfd_fork (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..a03de4b290 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,9 @@ #include #include #include +#include + +#include #define REMOTE_PATH "/dev/null" @@ -102,6 +106,41 @@ do_test (void) ppid = getpid (); puid = getuid (); + /* Sanity check for invalid inputs. */ + TEST_COMPARE (pidfd_getpid (-1), -1); + TEST_COMPARE (errno, EINVAL); + + { + pid_t pid = pidfd_getpid (STDOUT_FILENO); + TEST_COMPARE (pid, -1); + TEST_COMPARE (errno, EBADF); + } + + /* Check if pidfd_getpid returns ESRCH for exited subprocess. */ + { + int pidfd = pidfd_fork (0); + if (pidfd == 0) + exit (EXIT_SUCCESS); + + /* The process might be still running or already in zombie state, in any + case the PID is still allocated to the process. */ + pid_t pid = pidfd_getpid (pidfd); + if (pid > 0) + support_process_state_wait (pid, support_process_state_zombie); + + siginfo_t info; + TEST_COMPARE (waitid (P_PIDFD, pidfd, &info, WEXITED), 0); + 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 (pidfd); + TEST_COMPARE (pid, -1); + TEST_COMPARE (errno, ESRCH); + + xclose (pidfd); + } + TEST_COMPARE (socketpair (AF_UNIX, SOCK_STREAM, 0, sockets), 0); pid_t pid = xfork (); @@ -118,6 +157,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..c079ed5883 --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-pidfd_getpid.c @@ -0,0 +1,177 @@ +/* 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 +#include +#include + +#include + +static int sockfd[2]; + +static void +send_fd (const int sock, const int fd) +{ + union + { + struct cmsghdr hdr; + char buf[CMSG_SPACE (sizeof (int))]; + } cmsgbuf = {0}; + struct cmsghdr *cmsg; + char ch = 'A'; + struct iovec vec = + { + .iov_base = &ch, + .iov_len = sizeof ch + }; + struct msghdr msg = + { + .msg_control = &cmsgbuf.buf, + .msg_controllen = sizeof (cmsgbuf.buf), + .msg_iov = &vec, + .msg_iovlen = 1, + }; + + cmsg = CMSG_FIRSTHDR (&msg); + cmsg->cmsg_len = CMSG_LEN (sizeof (int)); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + memcpy (CMSG_DATA (cmsg), &fd, sizeof (fd)); + + ssize_t n; + while ((n = sendmsg (sock, &msg, 0)) == -1 && errno == EINTR); + + TEST_VERIFY_EXIT (n == 1); +} + +static int +recv_fd (const int sock) +{ + union + { + struct cmsghdr hdr; + char buf[CMSG_SPACE(sizeof(int))]; + } cmsgbuf = {0}; + struct cmsghdr *cmsg; + char ch = '\0'; + struct iovec vec = + { + .iov_base = &ch, + .iov_len = sizeof ch + }; + struct msghdr msg = + { + .msg_control = &cmsgbuf.buf, + .msg_controllen = sizeof (cmsgbuf.buf), + .msg_iov = &vec, + .msg_iovlen = 1, + }; + + ssize_t n; + while ((n = recvmsg (sock, &msg, 0)) == -1 && errno == EINTR); + if (n != 1 || ch != 'A') + return -1; + + cmsg = CMSG_FIRSTHDR (&msg); + if (cmsg == NULL) + return -1; + if (cmsg->cmsg_type != SCM_RIGHTS) + return -1; + + int fd = -1; + memcpy (&fd, CMSG_DATA (cmsg), sizeof (fd)); + if (fd < 0) + return -1; + return fd; +} + +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"); + } + + TEST_VERIFY_EXIT (socketpair (AF_UNIX, SOCK_STREAM, 0, sockfd) == 0); + + /* Check if pidfd_getpid returns EREMOTE for process not in current + namespace. */ + { + int pidfd = pidfd_fork (0); + TEST_VERIFY (pidfd >= 0); + if (pidfd == 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"); + } + + TEST_VERIFY_EXIT (mount (NULL, "/", NULL, MS_REC | MS_PRIVATE, 0) + == 0); + + pid_t child = xfork (); + if (child > 0) + { + int status; + xwaitpid (child, &status, 0); + TEST_VERIFY (WIFEXITED (status)); + exit (WEXITSTATUS (status)); + } + + /* Now that we're pid 1 (effectively "root") we can mount /proc */ + TEST_VERIFY_EXIT (mount ("proc", "/proc", "proc", 0, NULL) == 0); + + int ppidfd = recv_fd (sockfd[0]); + TEST_COMPARE (pidfd_getpid (ppidfd), -1); + TEST_COMPARE (errno, EREMOTE); + + exit (EXIT_SUCCESS); + } + + send_fd (sockfd[1], pidfd); + + siginfo_t info; + TEST_COMPARE (waitid (P_PIDFD, 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); + } + + 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 045205de0c..0726b6e8d0 100644 --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist @@ -2575,6 +2575,7 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 pidfd_fork F +GLIBC_2.38 pidfd_getpid F GLIBC_2.38 pidfd_spawn F GLIBC_2.38 pidfd_spawnp F GLIBC_2.4 __confstr_chk F diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist index 5a67604948..9c1f6830ba 100644 --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist @@ -2681,5 +2681,6 @@ GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F GLIBC_2.38 pidfd_fork F +GLIBC_2.38 pidfd_getpid F GLIBC_2.38 pidfd_spawn F GLIBC_2.38 pidfd_spawnp F