1.\" 2.\" Copyright (c) 2009-2010, 2012-2013 Robert N. M. Watson 3.\" All rights reserved. 4.\" 5.\" This software was developed at the University of Cambridge Computer 6.\" Laboratory with support from a grant from Google, Inc. 7.\" 8.\" This software was developed by SRI International and the University of 9.\" Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237) 10.\" ("CTSRD"), as part of the DARPA CRASH research programme. 11.\" 12.\" Redistribution and use in source and binary forms, with or without 13.\" modification, are permitted provided that the following conditions 14.\" are met: 15.\" 1. Redistributions of source code must retain the above copyright 16.\" notice, this list of conditions and the following disclaimer. 17.\" 2. Redistributions in binary form must reproduce the above copyright 18.\" notice, this list of conditions and the following disclaimer in the 19.\" documentation and/or other materials provided with the distribution. 20.\" 21.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 22.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 25.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31.\" SUCH DAMAGE. 32.\" 33.Dd April 19, 2026 34.Dt PDFORK 2 35.Os 36.Sh NAME 37.Nm pdfork , 38.Nm pdrfork , 39.Nm pdopenpid , 40.Nm pdgetpid , 41.Nm pdkill , 42.Nm pdwait 43.Nd System calls to manage process descriptors 44.Sh LIBRARY 45.Lb libc 46.Sh SYNOPSIS 47.In sys/procdesc.h 48.Ft pid_t 49.Fn pdfork "int *fdp" "int pdflags" 50.Ft pid_t 51.Fn pdrfork "int *fdp" "int pdflags" "int rfflags" 52.Ft int 53.Fn pdopenpid "pid_t pid" "int pdflags" 54.Ft int 55.Fn pdgetpid "int fd" "pid_t *pidp" 56.Ft int 57.Fn pdkill "int fd" "int signum" 58.Ft int 59.Fo pdwait 60.Fa "int fd" 61.Fa "int *status" 62.Fa "int options" 63.Fa "struct __wrusage *wrusage" 64.Fa "struct __siginfo *info" 65.Fc 66.Sh DESCRIPTION 67Process descriptors are special file descriptors that represent processes, 68and are created using 69.Fn pdfork , 70a variant of 71.Xr fork 2 , 72which, if successful, returns a process descriptor in the integer pointed to 73by 74.Fa fdp . 75Processes created via 76.Fn pdfork 77will not cause 78.Dv SIGCHLD 79on termination. 80.Fn pdfork 81can accept the 82.Fa pdflags: 83.Bl -tag -width PD_CLOEXEC 84.It Dv PD_DAEMON 85Instead of the default terminate-on-close behaviour, allow the process to 86live until it is explicitly killed with 87.Xr kill 2 . 88.Pp 89This option is not permitted in 90.Xr capsicum 4 91capability mode (see 92.Xr cap_enter 2 ) . 93.Pp 94Note: the option changes the behavior of 95.Xr close 2 96for the process descriptor returned by the operation. 97If there is another process descriptor for the same process, created without 98specifying the 99.Dv PD_DAEMON 100flag, closing that descriptor kills the process. 101.It Dv PD_CLOEXEC 102Set close-on-exec on process descriptor. 103.El 104.Pp 105The 106.Fn pdrfork 107system call is a variant of 108.Fn pdfork 109that also takes the 110.Fa rfflags 111argument to control sharing of process resources between the caller 112and the new process. 113Like 114.Fn pdfork , 115the function writes the process descriptor referencing the created 116process into the location pointed to by the 117.Fa fdp 118argument. 119See 120.Xr rfork 2 121for a description of the possible 122.Fa rfflag 123flags. 124The 125.Fn pdrfork 126system call requires that both the 127.Va RFPROC 128and 129.Va RFPROCDESC 130flags, or 131.Va RFSPAWN 132flag are specified. 133.Pp 134.Fn pdopenpid 135opens the process descriptor for the process specified by the argument 136.Fa pid . 137It takes the same flags in the 138.Fa pdflags 139argument as 140.Fn pdfork . 141The caller must have permission to debug the target process in order for 142.Fn pdopenpid 143to succeed. 144Zombie processes cannot be opened. 145.Pp 146There might be more that one file descriptor referencing the process. 147But only one caller of 148.Fn pdwait 149gets the exit status. 150After the zombie is reaped, calls to 151.Fn pdwait 152specifying any file descriptors for the same process fail with the 153.Er ESRCH 154error. 155.Pp 156.Fn pdgetpid 157queries the process ID (PID) in the process descriptor 158.Fa fd . 159.Pp 160.Fn pdkill 161is functionally identical to 162.Xr kill 2 , 163except that it accepts a process descriptor, 164.Fa fd , 165rather than a PID. 166.Pp 167The 168.Fn pdwait 169system call allows the calling thread to wait and retrieve 170the status information on the process referenced by the 171.Fa fd 172process descriptor. 173See the description of the 174.Xr wait6 175system call for the behavior specification. 176.Pp 177The following system calls also have effects specific to process descriptors: 178.Pp 179.Xr fstat 2 180queries status of a process descriptor; currently only the 181.Fa st_mode , 182.Fa st_birthtime , 183.Fa st_atime , 184.Fa st_ctime 185and 186.Fa st_mtime 187fields are defined. 188If the owner read, write, and execute bits are set then the 189process represented by the process descriptor is still alive. 190.Pp 191.Xr poll 2 192and 193.Xr select 2 194allow waiting for process state transitions; currently only 195.Dv POLLHUP 196is defined, and will be raised when the process dies. 197Process state transitions can also be monitored using 198.Xr kqueue 2 199filter 200.Dv EVFILT_PROCDESC ; 201currently only 202.Dv NOTE_EXIT 203is implemented. 204.Pp 205.Xr close 2 206will close the process descriptor unless 207.Dv PD_DAEMON 208is set; if the process is still alive and this is 209the last reference to the process descriptor, the process will be terminated 210with the signal 211.Dv SIGKILL . 212The PID of the referenced process is not reused until the process 213descriptor is closed, 214whether or not the zombie process is reaped by 215.Fn pdwait , 216.Xr wait6 , 217or similar system calls. 218.Sh RETURN VALUES 219.Fn pdfork 220and 221.Fn pdrfork 222return a PID, 0 or -1, as 223.Xr fork 2 224does. 225.Pp 226.Fn pdopenpid , 227.Fn pdgetpid , 228.Fn pdkill , 229and 230.Fn pdwait 231return 0 on success and -1 on failure. 232.Sh ERRORS 233These functions may return the same error numbers as their PID-based equivalents 234(e.g. 235.Fn pdfork 236may return the same error numbers as 237.Xr fork 2 ) , 238with the following additions: 239.Bl -tag -width Er 240.It Bq Er EFAULT 241The copyout of the resulting file descriptor value to the memory pointed 242to by 243.Fa fdp 244failed. 245.Pp 246Note that the child process was already created when this condition 247is detected, 248and the child continues execution, same as the parent. 249If this error must be handled, it is advisable to memoize the 250.Fn getpid 251result before the call to 252.Fn pdfork 253or 254.Fn pdrfork , 255and compare it to the value returned by 256.Fn getpid 257after, to see if code is executing in parent or child. 258.It Bq Er EINVAL 259The signal number given to 260.Fn pdkill 261is invalid. 262.It Bq Er ENOTCAPABLE 263The process descriptor being operated on has insufficient rights (e.g. 264.Dv CAP_PDKILL 265for 266.Fn pdkill ) . 267.It Bq Er EINVAL 268The 269.Fn pdwait 270function is called with reserved bits set in 271.Fa options . 272.El 273.Pp 274The 275.Fn pdopenpid 276might return the same errors as 277.Xr open 2 , 278related to the file descriptor allocation problems, as well as the 279following specific errors: 280.Bl -tag -width Er 281.It Bq Er EINVAL 282The 283.Fa flags 284argument has reserved bits set. 285.It Bq Er ECAPMODE 286.Fn pdopenpid 287is called by the process in capability mode. 288.It Bq Er EBUSY 289The process specified by the 290.Fa pid 291argument already terminated. 292.It Bq Er ESRCH 293The process specified by the 294.Fa pid 295argument does not exist, or the caller does not have enough privileges 296to open the process. 297.It Bq Er EMFILE 298The calling process already reached its limit for open file descriptors. 299.Pp 300Current implementation installs the opened process descriptor into the 301calling process's file descriptors table. 302If the descriptor cannot be installed, the process descriptor is closed, 303which executes all actions performed by 304.Xr close 2 305on it. 306.El 307.Sh SEE ALSO 308.Xr close 2 , 309.Xr fork 2 , 310.Xr fstat 2 , 311.Xr kill 2 , 312.Xr kqueue 2 , 313.Xr poll 2 , 314.Xr wait4 2 , 315.Xr capsicum 4 , 316.Xr procdesc 4 317.Sh HISTORY 318The 319.Fn pdfork , 320.Fn pdgetpid , 321and 322.Fn pdkill 323system calls first appeared in 324.Fx 9.0 . 325The 326.Fn pdrfork 327and 328.Fn pdwait 329system calls first appeared in 330.Fx 15.1 . 331The 332.Fn pdopenpid 333system call first appeared in 334.Fx 16.0 . 335.Pp 336Support for process descriptors mode was developed as part of the 337.Tn TrustedBSD 338Project. 339.Sh AUTHORS 340.An -nosplit 341These functions and the capability facility were created by 342.An Robert N. M. Watson Aq Mt rwatson@FreeBSD.org 343and 344.An Jonathan Anderson Aq Mt jonathan@FreeBSD.org 345at the University of Cambridge Computer Laboratory with support from a grant 346from Google, Inc. 347The 348.Fn pdrfork 349and 350.Fn pdwait 351functions were developed by 352.An Konstantin Belousov Aq Mt kib@FreeBSD.org 353with input from 354.An Alan Somers Aq Mt asomers@FreeBSD.org . 355The 356.Fn pdopenpid 357function was developed by 358.An Konstantin Belousov Aq Mt kib@FreeBSD.org . 359