From patchwork Tue May 23 13:27:49 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: 1785146 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org 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=sourceware.org; envelope-from=libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org; receiver=) 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=a/MkuUmG; dkim-atps=neutral Received: from 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 (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4QQZtV5N3Yz2020 for ; Tue, 23 May 2023 23:29:54 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 840FD3857029 for ; Tue, 23 May 2023 13:29:52 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 840FD3857029 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1684848592; bh=nLen/pkTViJ0wkn7X2nGAxDOM/yU0BVRHUXU0zw+3q8=; 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=a/MkuUmGIL28wbnMY9KHzoHcdCHz9ADiZpZTxgHhY0vk7u9oCeLUfOkek0Qw2ggOb ZPyHt5PzRHzhKMWiIx+Gt7PpCIZ7S7rWulUYOnlwGSmjI/5wGWBg/+UVNo+qXOW5CG FuGjYZ+X01qwSTGZPgX3Q7UlS6diMQmPQJI4/isA= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-oa1-x30.google.com (mail-oa1-x30.google.com [IPv6:2001:4860:4864:20::30]) by sourceware.org (Postfix) with ESMTPS id 7FCAC3858C00 for ; Tue, 23 May 2023 13:28:05 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 7FCAC3858C00 Received: by mail-oa1-x30.google.com with SMTP id 586e51a60fabf-19c7e1acf9eso1335289fac.1 for ; Tue, 23 May 2023 06:28:05 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1684848484; x=1687440484; 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=nLen/pkTViJ0wkn7X2nGAxDOM/yU0BVRHUXU0zw+3q8=; b=DPHRR25AWMi7eFOBB1xnD7JlYHQPY1MXTQG8k9D2DK1j6xG5G2MqTMgq66ifnK5PVq uCy/HPG0RtYuqAHZ3hB5L20vPLtaoeaZ25X+Ixr16sdy/8ho3h05QC0Qpk9HLjhwEnRW moVxO8tSIol604DGMPSniDL/2FD5a1CpXVcfZoOfn53PsSr6QIKG/Z5Dn9mrWgmenfEh Il/mPQRBggUqS5tQ9eb9o14bz28UAj0ldj/k5YkAx96LCSh5oT9IqBP7IpoOgOE9CP94 dgKNQBfq095dXhhmbo8rc3L5AMzLGTlsAQecG6R1Pwe2CPK2hxYVl8RHwKqFSOSBaULl 3Aqg== X-Gm-Message-State: AC+VfDzymyPYbG80J+J87lZDbag7PSRM7iHYsLFZBi97H18sB6dRUb8l E1gmzy8Ohy5HBZO420mcU/jBx/7WYXYLmNH68nH6tA== X-Google-Smtp-Source: ACHHUZ7as7vgpWFX/Pb6em+C49/MaHK+avRcDonYTiwm9FgOswJ8fNEKoMgttrXwhvZcazgCJ3K/XQ== X-Received: by 2002:a05:6870:b144:b0:196:43e8:3030 with SMTP id a4-20020a056870b14400b0019643e83030mr4916496oal.39.1684848483591; Tue, 23 May 2023 06:28:03 -0700 (PDT) Received: from mandiga.. ([2804:1b3:a7c1:2e05:abff:50e6:a79d:43f4]) by smtp.gmail.com with ESMTPSA id t3-20020a9d5903000000b006a43519523fsm3397047oth.1.2023.05.23.06.28.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 23 May 2023 06:28:02 -0700 (PDT) To: libc-alpha@sourceware.org, Luca Boccassi , Florian Weimer , Philip Withnall Subject: [PATCH v5 4/4] linux: Add pidfd_getpid Date: Tue, 23 May 2023 10:27:49 -0300 Message-Id: <20230523132749.1646124-5-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230523132749.1646124-1-adhemerval.zanella@linaro.org> References: <20230523132749.1646124-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, 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+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 associatedi, or 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). Acked-by: Luca Boccassi --- NEWS | 4 + manual/process.texi | 31 +++ 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 | 122 ++++++++++++ .../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 | 47 +++++ sysdeps/unix/sysv/linux/tst-pidfd_getpid.c | 182 ++++++++++++++++++ .../unix/sysv/linux/x86_64/64/libc.abilist | 1 + .../unix/sysv/linux/x86_64/x32/libc.abilist | 1 + 44 files changed, 567 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 c99458ed26..5965f5e19f 100644 --- a/NEWS +++ b/NEWS @@ -47,6 +47,10 @@ Major new features: of return a process ID, it returns a file descriptor that can be used along other pidfd functions. +* On Linux, the pidfd_getpid fcuntsion 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 80fdc808f0..d44fd4266d 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 @@ -397,6 +398,36 @@ Do not send a @code{SIGCHLD} termination signal when child terminates. This function is specific to Linux. +@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. +@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 675c226a99..680bb52e64 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 \ @@ -490,8 +491,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..46848a5983 --- /dev/null +++ b/sysdeps/unix/sysv/linux/pidfd_getpid.c @@ -0,0 +1,122 @@ +/* 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; + case '+': l++; + } + + if (*l == '\0') + return 0; + + int n = 0; + while (*l != '\0') + { + /* Check if '*l' is a digit. */ + if ((unsigned int)(*l) - '0' >= 10) + return 0; + + /* Ignore invalid large values. */ + if (INT_MULTIPLY_WRAPV (10, n, &n) + || INT_ADD_WRAPV (n, *l++ - '0', &n)) + return 0; + } + + /* -1 indicates that the process is terminated. */ + if (neg && n != 1) + return 0; + + 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) == -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 451718aebe..bda0316089 100644 --- a/sysdeps/unix/sysv/linux/sys/pidfd.h +++ b/sysdeps/unix/sysv/linux/sys/pidfd.h @@ -62,4 +62,8 @@ extern int pidfd_send_signal (int __pidfd, int __sig, siginfo_t *__info, process to the parent process. */ extern pid_t pidfd_fork (int *pidfd, 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..7fbc85aacb 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,43 @@ 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. */ + { + int pidfd; + pid_t pidfork = pidfd_fork (&pidfd, 0); + if (pidfork == 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_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 (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 +159,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..d2647c8ae1 --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-pidfd_getpid.c @@ -0,0 +1,182 @@ +/* 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; + pid_t pid = pidfd_fork (&pidfd, 0); + TEST_VERIFY_EXIT (pid >= 0); + if (pid == 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 */ + if (mount ("proc", "/proc", "proc", 0, NULL) != 0) + /* This happens if we're trying to create a nested container, + like if the build is running under podman, and we lack + priviledges. */ + exit (EXIT_UNSUPPORTED); + + 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