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 134The 135.Fn pdopenpid 136function opens the process descriptor for the process 137specified by the argument 138.Fa pid . 139It takes the same flags in the 140.Fa pdflags 141argument as 142.Fn pdfork . 143The caller must have permission to debug the target process in order for 144.Fn pdopenpid 145to succeed. 146Zombie processes cannot be opened. 147.Pp 148There might be more that one file descriptor referencing the process. 149But only one caller of 150.Fn pdwait 151gets the exit status. 152After the zombie is reaped, calls to 153.Fn pdwait 154specifying any file descriptors for the same process fail with the 155.Er ESRCH 156error. 157.Pp 158.Fn pdgetpid 159queries the process ID (PID) in the process descriptor 160.Fa fd . 161.Pp 162.Fn pdkill 163is functionally identical to 164.Xr kill 2 , 165except that it accepts a process descriptor, 166.Fa fd , 167rather than a PID. 168.Pp 169The 170.Fn pdwait 171system call allows the calling thread to wait and retrieve 172the status information on the process referenced by the 173.Fa fd 174process descriptor. 175See the description of the 176.Xr wait6 177system call for the behavior specification. 178.Pp 179The following system calls also have effects specific to process descriptors: 180.Pp 181.Xr fstat 2 182queries status of a process descriptor; currently only the 183.Fa st_mode , 184.Fa st_birthtime , 185.Fa st_atime , 186.Fa st_ctime 187and 188.Fa st_mtime 189fields are defined. 190If the owner read, write, and execute bits are set then the 191process represented by the process descriptor is still alive. 192.Pp 193.Xr poll 2 194and 195.Xr select 2 196allow waiting for process state transitions; currently only 197.Dv POLLHUP 198is defined, and will be raised when the process dies. 199Process state transitions can also be monitored using 200.Xr kqueue 2 201filter 202.Dv EVFILT_PROCDESC ; 203currently only 204.Dv NOTE_EXIT 205is implemented. 206.Pp 207.Xr close 2 208will close the process descriptor unless 209.Dv PD_DAEMON 210is set; if the process is still alive and this is 211the last reference to the process descriptor, the process will be terminated 212with the signal 213.Dv SIGKILL . 214The PID of the referenced process is not reused until the process 215descriptor is closed, 216whether or not the zombie process is reaped by 217.Fn pdwait , 218.Xr wait6 , 219or similar system calls. 220.Sh RETURN VALUES 221.Fn pdfork 222and 223.Fn pdrfork 224return a PID, 0 or -1, as 225.Xr fork 2 226does. 227.Pp 228.Fn pdopenpid , 229.Fn pdgetpid , 230.Fn pdkill , 231and 232.Fn pdwait 233return 0 on success and -1 on failure. 234.Sh ERRORS 235These functions may return the same error numbers as their PID-based equivalents 236(e.g. 237.Fn pdfork 238may return the same error numbers as 239.Xr fork 2 ) , 240with the following additions: 241.Bl -tag -width Er 242.It Bq Er EFAULT 243The copyout of the resulting file descriptor value to the memory pointed 244to by 245.Fa fdp 246failed. 247.Pp 248Note that the child process was already created when this condition 249is detected, 250and the child continues execution, same as the parent. 251If this error must be handled, it is advisable to memoize the 252.Fn getpid 253result before the call to 254.Fn pdfork 255or 256.Fn pdrfork , 257and compare it to the value returned by 258.Fn getpid 259after, to see if code is executing in parent or child. 260.It Bq Er EINVAL 261The signal number given to 262.Fn pdkill 263is invalid. 264.It Bq Er ENOTCAPABLE 265The process descriptor being operated on has insufficient rights (e.g. 266.Dv CAP_PDKILL 267for 268.Fn pdkill ) . 269.It Bq Er EINVAL 270The 271.Fn pdwait 272function is called with reserved bits set in 273.Fa options . 274.El 275.Pp 276The 277.Fn pdopenpid 278might return the same errors as 279.Xr open 2 , 280related to the file descriptor allocation problems, as well as the 281following specific errors: 282.Bl -tag -width Er 283.It Bq Er EINVAL 284The 285.Fa flags 286argument has reserved bits set. 287.It Bq Er ECAPMODE 288.Fn pdopenpid 289is called by the process in capability mode. 290.It Bq Er EBUSY 291The process specified by the 292.Fa pid 293argument already terminated. 294.It Bq Er ESRCH 295The process specified by the 296.Fa pid 297argument does not exist, or the caller does not have enough privileges 298to open the process. 299.It Bq Er EMFILE 300The calling process already reached its limit for open file descriptors. 301.Pp 302Current implementation installs the opened process descriptor into the 303calling process's file descriptors table. 304If the descriptor cannot be installed, the process descriptor is closed, 305which executes all actions performed by 306.Xr close 2 307on it. 308.El 309.Sh SEE ALSO 310.Xr close 2 , 311.Xr fork 2 , 312.Xr fstat 2 , 313.Xr kill 2 , 314.Xr kqueue 2 , 315.Xr poll 2 , 316.Xr wait4 2 , 317.Xr capsicum 4 , 318.Xr procdesc 4 319.Sh HISTORY 320The 321.Fn pdfork , 322.Fn pdgetpid , 323and 324.Fn pdkill 325system calls first appeared in 326.Fx 9.0 . 327The 328.Fn pdrfork 329and 330.Fn pdwait 331system calls first appeared in 332.Fx 15.1 . 333The 334.Fn pdopenpid 335system call first appeared in 336.Fx 16.0 . 337.Pp 338Support for process descriptors mode was developed as part of the 339.Tn TrustedBSD 340Project. 341.Sh AUTHORS 342.An -nosplit 343These functions and the capability facility were created by 344.An Robert N. M. Watson Aq Mt rwatson@FreeBSD.org 345and 346.An Jonathan Anderson Aq Mt jonathan@FreeBSD.org 347at the University of Cambridge Computer Laboratory with support from a grant 348from Google, Inc. 349The 350.Fn pdrfork 351and 352.Fn pdwait 353functions were developed by 354.An Konstantin Belousov Aq Mt kib@FreeBSD.org 355with input from 356.An Alan Somers Aq Mt asomers@FreeBSD.org . 357The 358.Fn pdopenpid 359function was developed by 360.An Konstantin Belousov Aq Mt kib@FreeBSD.org . 361