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. 198Certain file descriptor types cannot be copied this way, namely 199kqueues. 200.Pp 201The following system calls also have effects specific to process descriptors: 202.Pp 203.Xr fstat 2 204queries status of a process descriptor; currently only the 205.Fa st_mode , 206.Fa st_birthtime , 207.Fa st_atime , 208.Fa st_ctime 209and 210.Fa st_mtime 211fields are defined. 212If the owner read, write, and execute bits are set then the 213process represented by the process descriptor is still alive. 214.Pp 215.Xr poll 2 216and 217.Xr select 2 218allow waiting for process state transitions; currently only 219.Dv POLLHUP 220is defined, and will be raised when the process dies. 221Process state transitions can also be monitored using 222.Xr kqueue 2 223filter 224.Dv EVFILT_PROCDESC ; 225currently only 226.Dv NOTE_EXIT 227is implemented. 228.Pp 229.Xr close 2 230will close the process descriptor unless 231.Dv PD_DAEMON 232is set; if the process is still alive and this is 233the last reference to the process descriptor, the process will be terminated 234with the signal 235.Dv SIGKILL . 236The PID of the referenced process is not reused until the process 237descriptor is closed, 238whether or not the zombie process is reaped by 239.Fn pdwait , 240.Xr wait6 , 241or similar system calls. 242.Sh RETURN VALUES 243.Fn pdfork 244and 245.Fn pdrfork 246return a PID, 0 or -1, as 247.Xr fork 2 248does. 249.Pp 250.Fn pdopenpid , 251.Fn pdgetpid , 252.Fn pdkill , 253.Fn pdwait , 254and 255.Fn pddupfd 256return 0 on success and -1 on failure. 257.Sh ERRORS 258These functions may return the same error numbers as their PID-based equivalents 259(e.g. 260.Fn pdfork 261may return the same error numbers as 262.Xr fork 2 ) , 263with the following additions: 264.Bl -tag -width Er 265.It Bq Er EFAULT 266The copyout of the resulting file descriptor value to the memory pointed 267to by 268.Fa fdp 269failed. 270.Pp 271Note that the child process was already created when this condition 272is detected, 273and the child continues execution, same as the parent. 274If this error must be handled, it is advisable to memoize the 275.Fn getpid 276result before the call to 277.Fn pdfork 278or 279.Fn pdrfork , 280and compare it to the value returned by 281.Fn getpid 282after, to see if code is executing in parent or child. 283.It Bq Er EINVAL 284The signal number given to 285.Fn pdkill 286is invalid. 287.It Bq Er ENOTCAPABLE 288The process descriptor being operated on has insufficient rights (e.g. 289.Dv CAP_PDKILL 290for 291.Fn pdkill ) . 292.It Bq Er EINVAL 293The 294.Fn pdwait 295function is called with reserved bits set in 296.Fa options . 297.El 298.Pp 299The 300.Fn pdopenpid 301might return the same errors as 302.Xr open 2 , 303related to the file descriptor allocation problems, as well as the 304following specific errors: 305.Bl -tag -width Er 306.It Bq Er EINVAL 307The 308.Fa flags 309argument has reserved bits set. 310.It Bq Er ECAPMODE 311.Fn pdopenpid 312is called by the process in capability mode. 313.It Bq Er EBUSY 314The process specified by the 315.Fa pid 316argument already terminated. 317.It Bq Er ESRCH 318The process specified by the 319.Fa pid 320argument does not exist, or the caller does not have enough privileges 321to open the process. 322.It Bq Er EMFILE 323The calling process already reached its limit for open file descriptors. 324.Pp 325Current implementation installs the opened process descriptor into the 326calling process's file descriptors table. 327If the descriptor cannot be installed, the process descriptor is closed, 328which executes all actions performed by 329.Xr close 2 330on it. 331.El 332.Pp 333The 334.Fn pddupfd 335returns the following errors: 336.Bl -tag -width Er 337.It Bq Er EINVAL 338The 339.Fa flags 340argument is not zero. 341.It Bq Er ESRCH 342The process specified by the file descriptor 343.Fa fd 344exited. 345.It Bq Er EBADF 346The file descriptor 347.Fa fd 348is not a process file descriptor. 349.It Bq Er EBADF 350The file descriptor 351.Fa remotefd 352is not a valid file descriptor in the specified process. 353.It Bq Er ENOENT 354The specified process does not have a file descriptor table. 355.It Bq Er EOPNOTSUPP 356.Fa remotefd 357refers to a file that cannot be duplicated across a process boundary, 358such as a kqueue. 359.El 360.Sh SEE ALSO 361.Xr close 2 , 362.Xr fork 2 , 363.Xr fstat 2 , 364.Xr kill 2 , 365.Xr kqueue 2 , 366.Xr poll 2 , 367.Xr wait4 2 , 368.Xr capsicum 4 , 369.Xr procdesc 4 370.Sh HISTORY 371The 372.Fn pdfork , 373.Fn pdgetpid , 374and 375.Fn pdkill 376system calls first appeared in 377.Fx 9.0 . 378The 379.Fn pdrfork 380and 381.Fn pdwait 382system calls first appeared in 383.Fx 15.1 . 384The 385.Fn pdopenpid 386and 387.Fn pddupfd 388system calls first appeared in 389.Fx 16.0 . 390.Pp 391Support for process descriptors mode was developed as part of the 392.Tn TrustedBSD 393Project. 394.Sh AUTHORS 395.An -nosplit 396These functions and the capability facility were created by 397.An Robert N. M. Watson Aq Mt rwatson@FreeBSD.org 398and 399.An Jonathan Anderson Aq Mt jonathan@FreeBSD.org 400at the University of Cambridge Computer Laboratory with support from a grant 401from Google, Inc. 402The 403.Fn pdrfork 404and 405.Fn pdwait 406functions were developed by 407.An Konstantin Belousov Aq Mt kib@FreeBSD.org 408with input from 409.An Alan Somers Aq Mt asomers@FreeBSD.org . 410The 411.Fn pdopenpid 412and 413.Fn pddupfd 414functions were developed by 415.An Konstantin Belousov Aq Mt kib@FreeBSD.org . 416