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.Nm pddupfd 44.Nd System calls to manage process descriptors 45.Sh LIBRARY 46.Lb libc 47.Sh SYNOPSIS 48.In sys/procdesc.h 49.Ft pid_t 50.Fn pdfork "int *fdp" "int pdflags" 51.Ft pid_t 52.Fn pdrfork "int *fdp" "int pdflags" "int rfflags" 53.Ft int 54.Fn pdopenpid "pid_t pid" "int pdflags" 55.Ft int 56.Fn pdgetpid "int fd" "pid_t *pidp" 57.Ft int 58.Fn pdkill "int fd" "int signum" 59.Ft int 60.Fo pdwait 61.Fa "int fd" 62.Fa "int *status" 63.Fa "int options" 64.Fa "struct __wrusage *wrusage" 65.Fa "struct __siginfo *info" 66.Fc 67.Ft int 68.Fn pddupfd "int fd" "int remotefd" "int flags" 69.Sh DESCRIPTION 70Process descriptors are special file descriptors that represent processes, 71and are created using 72.Fn pdfork , 73a variant of 74.Xr fork 2 , 75which, if successful, returns a process descriptor in the integer pointed to 76by 77.Fa fdp . 78Processes created via 79.Fn pdfork 80will not cause 81.Dv SIGCHLD 82on termination. 83.Fn pdfork 84can accept the 85.Fa pdflags: 86.Bl -tag -width PD_CLOEXEC 87.It Dv PD_DAEMON 88Instead of the default terminate-on-close behaviour, allow the process to 89live until it is explicitly killed with 90.Xr kill 2 . 91.Pp 92This option is not permitted in 93.Xr capsicum 4 94capability mode (see 95.Xr cap_enter 2 ) . 96.Pp 97Note: the option changes the behavior of 98.Xr close 2 99for the process descriptor returned by the operation. 100If there is another process descriptor for the same process, created without 101specifying the 102.Dv PD_DAEMON 103flag, closing that descriptor kills the process. 104.It Dv PD_CLOEXEC 105Set close-on-exec on process descriptor. 106.El 107.Pp 108The 109.Fn pdrfork 110system call is a variant of 111.Fn pdfork 112that also takes the 113.Fa rfflags 114argument to control sharing of process resources between the caller 115and the new process. 116Like 117.Fn pdfork , 118the function writes the process descriptor referencing the created 119process into the location pointed to by the 120.Fa fdp 121argument. 122See 123.Xr rfork 2 124for a description of the possible 125.Fa rfflag 126flags. 127The 128.Fn pdrfork 129system call requires that both the 130.Va RFPROC 131and 132.Va RFPROCDESC 133flags, or 134.Va RFSPAWN 135flag are specified. 136.Pp 137The 138.Fn pdopenpid 139function opens the process descriptor for the process 140specified by the argument 141.Fa pid . 142It takes the same flags in the 143.Fa pdflags 144argument as 145.Fn pdfork . 146The caller must have permission to debug the target process in order for 147.Fn pdopenpid 148to succeed. 149Zombie processes cannot be opened. 150.Pp 151There might be more that one file descriptor referencing the process. 152But only one caller of 153.Fn pdwait 154gets the exit status. 155After the zombie is reaped, calls to 156.Fn pdwait 157specifying any file descriptors for the same process fail with the 158.Er ESRCH 159error. 160.Pp 161.Fn pdgetpid 162queries the process ID (PID) in the process descriptor 163.Fa fd . 164.Pp 165.Fn pdkill 166is functionally identical to 167.Xr kill 2 , 168except that it accepts a process descriptor, 169.Fa fd , 170rather than a PID. 171.Pp 172The 173.Fn pdwait 174system call allows the calling thread to wait and retrieve 175the status information on the process referenced by the 176.Fa fd 177process descriptor. 178See the description of the 179.Xr wait6 180system call for the behavior specification. 181.Pp 182The 183.Fn pddupfd 184function allows the caller to duplicate a file descriptor 185across the process boundaries. 186The function returns the new file descriptor that points to the same file 187as the file descriptor 188.Fa remotefd 189in the process specified by the 190.Fa fd 191process descriptor. 192The returned file descriptor has the 193.Va O_CLOEXEC 194flag set. 195The 196.Fa flags 197argument is reserved and must be zero. 198.Pp 199The following system calls also have effects specific to process descriptors: 200.Pp 201.Xr fstat 2 202queries status of a process descriptor; currently only the 203.Fa st_mode , 204.Fa st_birthtime , 205.Fa st_atime , 206.Fa st_ctime 207and 208.Fa st_mtime 209fields are defined. 210If the owner read, write, and execute bits are set then the 211process represented by the process descriptor is still alive. 212.Pp 213.Xr poll 2 214and 215.Xr select 2 216allow waiting for process state transitions; currently only 217.Dv POLLHUP 218is defined, and will be raised when the process dies. 219Process state transitions can also be monitored using 220.Xr kqueue 2 221filter 222.Dv EVFILT_PROCDESC ; 223currently only 224.Dv NOTE_EXIT 225is implemented. 226.Pp 227.Xr close 2 228will close the process descriptor unless 229.Dv PD_DAEMON 230is set; if the process is still alive and this is 231the last reference to the process descriptor, the process will be terminated 232with the signal 233.Dv SIGKILL . 234The PID of the referenced process is not reused until the process 235descriptor is closed, 236whether or not the zombie process is reaped by 237.Fn pdwait , 238.Xr wait6 , 239or similar system calls. 240.Sh RETURN VALUES 241.Fn pdfork 242and 243.Fn pdrfork 244return a PID, 0 or -1, as 245.Xr fork 2 246does. 247.Pp 248.Fn pdopenpid , 249.Fn pdgetpid , 250.Fn pdkill , 251.Fn pdwait , 252and 253.Fn pddupfd 254return 0 on success and -1 on failure. 255.Sh ERRORS 256These functions may return the same error numbers as their PID-based equivalents 257(e.g. 258.Fn pdfork 259may return the same error numbers as 260.Xr fork 2 ) , 261with the following additions: 262.Bl -tag -width Er 263.It Bq Er EFAULT 264The copyout of the resulting file descriptor value to the memory pointed 265to by 266.Fa fdp 267failed. 268.Pp 269Note that the child process was already created when this condition 270is detected, 271and the child continues execution, same as the parent. 272If this error must be handled, it is advisable to memoize the 273.Fn getpid 274result before the call to 275.Fn pdfork 276or 277.Fn pdrfork , 278and compare it to the value returned by 279.Fn getpid 280after, to see if code is executing in parent or child. 281.It Bq Er EINVAL 282The signal number given to 283.Fn pdkill 284is invalid. 285.It Bq Er ENOTCAPABLE 286The process descriptor being operated on has insufficient rights (e.g. 287.Dv CAP_PDKILL 288for 289.Fn pdkill ) . 290.It Bq Er EINVAL 291The 292.Fn pdwait 293function is called with reserved bits set in 294.Fa options . 295.El 296.Pp 297The 298.Fn pdopenpid 299might return the same errors as 300.Xr open 2 , 301related to the file descriptor allocation problems, as well as the 302following specific errors: 303.Bl -tag -width Er 304.It Bq Er EINVAL 305The 306.Fa flags 307argument has reserved bits set. 308.It Bq Er ECAPMODE 309.Fn pdopenpid 310is called by the process in capability mode. 311.It Bq Er EBUSY 312The process specified by the 313.Fa pid 314argument already terminated. 315.It Bq Er ESRCH 316The process specified by the 317.Fa pid 318argument does not exist, or the caller does not have enough privileges 319to open the process. 320.It Bq Er EMFILE 321The calling process already reached its limit for open file descriptors. 322.Pp 323Current implementation installs the opened process descriptor into the 324calling process's file descriptors table. 325If the descriptor cannot be installed, the process descriptor is closed, 326which executes all actions performed by 327.Xr close 2 328on it. 329.El 330.Pp 331The 332.Fn pddupfd 333returns the following errors: 334.Bl -tag -width Er 335.It Bq Er EINVAL 336The 337.Fa flags 338argument is not zero. 339.It Bq Er ESRCH 340The process specified by the file descriptor 341.Fa fd 342exited. 343.It Bq Er EBADF 344The file descriptor 345.Fa fd 346is not a process file descriptor. 347.It Bq Er EBADF 348The file descriptor 349.Fa remotefd 350is not a valid file descriptor in the specified process. 351.It Bq Er ENOENT 352The specified process does not have a file descriptor table. 353.El 354.Sh SEE ALSO 355.Xr close 2 , 356.Xr fork 2 , 357.Xr fstat 2 , 358.Xr kill 2 , 359.Xr kqueue 2 , 360.Xr poll 2 , 361.Xr wait4 2 , 362.Xr capsicum 4 , 363.Xr procdesc 4 364.Sh HISTORY 365The 366.Fn pdfork , 367.Fn pdgetpid , 368and 369.Fn pdkill 370system calls first appeared in 371.Fx 9.0 . 372The 373.Fn pdrfork 374and 375.Fn pdwait 376system calls first appeared in 377.Fx 15.1 . 378The 379.Fn pdopenpid 380and 381.Fn pddupfd 382system calls first appeared in 383.Fx 16.0 . 384.Pp 385Support for process descriptors mode was developed as part of the 386.Tn TrustedBSD 387Project. 388.Sh AUTHORS 389.An -nosplit 390These functions and the capability facility were created by 391.An Robert N. M. Watson Aq Mt rwatson@FreeBSD.org 392and 393.An Jonathan Anderson Aq Mt jonathan@FreeBSD.org 394at the University of Cambridge Computer Laboratory with support from a grant 395from Google, Inc. 396The 397.Fn pdrfork 398and 399.Fn pdwait 400functions were developed by 401.An Konstantin Belousov Aq Mt kib@FreeBSD.org 402with input from 403.An Alan Somers Aq Mt asomers@FreeBSD.org . 404The 405.Fn pdopenpid 406and 407.Fn pddupfd 408functions were developed by 409.An Konstantin Belousov Aq Mt kib@FreeBSD.org . 410