xref: /freebsd/lib/libsys/pdfork.2 (revision d15f2551b25f79ddcbe289faa95e655100b952da)
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.It Dv PD_NOWAITPID
107The parent cannot obtain the child's status with
108.Xr waitpid 2 .
109.El
110.Pp
111The
112.Fn pdrfork
113system call is a variant of
114.Fn pdfork
115that also takes the
116.Fa rfflags
117argument to control sharing of process resources between the caller
118and the new process.
119Like
120.Fn pdfork ,
121the function writes the process descriptor referencing the created
122process into the location pointed to by the
123.Fa fdp
124argument.
125See
126.Xr rfork 2
127for a description of the possible
128.Fa rfflag
129flags.
130The
131.Fn pdrfork
132system call requires that both the
133.Va RFPROC
134and
135.Va RFPROCDESC
136flags, or
137.Va RFSPAWN
138flag are specified.
139.Pp
140The
141.Fn pdopenpid
142function opens the process descriptor for the process
143specified by the argument
144.Fa pid .
145It takes the same flags in the
146.Fa pdflags
147argument as
148.Fn pdfork .
149The caller must have permission to debug the target process in order for
150.Fn pdopenpid
151to succeed.
152Zombie processes cannot be opened.
153.Pp
154There might be more that one file descriptor referencing the process.
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 2
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.Sh INTERACTION OF PROCESS DESCRIPTORS AND Xr WAITPID 2
201.Pp
202The
203.Fn pdwait
204system call may be called on a process descriptor
205an unlimited number of times.
206In particular, it does not reap the target process,
207even if that process has exited.
208Each time, it returns the same status.
209.Bl -dash
210.It
211If the process was forked with
212.Fn pdfork ,
213and the
214.Dv PD_NOWAITPID
215flag was specified, then the process is automatically reaped after the
216last process descriptor referencing that process is closed.
217No
218.Xr waitpid 2
219call
220.Pq or a call from the same family of the wait functions which operate on PIDs
221are needed to reap the zombie process.
222.It
223If the process was created by
224.Fn pdfork ,
225and the
226.Dv PD_NOWAITPID
227flag was not specified, then after exiting,
228the process will not be reaped until the parent or reaper has called
229.Xr waitpid 2
230and all process descriptors referencing the process are closed.
231.It
232If the process was created by the
233.Xr fork 2
234system call
235.Pq which does not allocate a process descriptor for the child ,
236and later the process was opened by
237.Fn pdopenpid ,
238then a
239.Xr waitpid 2
240call from the parent is needed to reap the exited child.
241.El
242.Pp
243In any case, the PID of the process is not reused until its zombie
244is reaped, and all its process descriptors are closed.
245.Pp
246A debugger attached by
247.Xr ptrace 2
248can execute the
249.Fn waitpid
250calls against the alive target regardless of the way
251the target process was forked.
252.Sh INTERACTION OF PROCESS DESCRIPTORS WITH OTHER SYSTEM CALLS
253.Pp
254The following system calls also have effects specific to process descriptors:
255.Pp
256.Xr fstat 2
257queries status of a process descriptor; currently only the
258.Fa st_mode ,
259.Fa st_birthtime ,
260.Fa st_atime ,
261.Fa st_ctime
262and
263.Fa st_mtime
264fields are defined.
265If the owner read, write, and execute bits are set then the
266process represented by the process descriptor is still alive.
267.Pp
268.Xr poll 2
269and
270.Xr select 2
271allow waiting for process state transitions; currently only
272.Dv POLLHUP
273is defined, and will be raised when the process dies.
274Process state transitions can also be monitored using
275.Xr kqueue 2
276filter
277.Dv EVFILT_PROCDESC ;
278currently only
279.Dv NOTE_EXIT
280is implemented.
281.Pp
282.Xr close 2
283will close the process descriptor unless
284.Dv PD_DAEMON
285is set; if the process is still alive and this is
286the last reference to the process descriptor, the process will be terminated
287with the signal
288.Dv SIGKILL .
289The PID of the referenced process is not reused until the process
290descriptor is closed,
291whether or not the zombie process is reaped by
292.Fn pdwait ,
293.Xr wait6 ,
294or similar system calls.
295.Sh RETURN VALUES
296.Fn pdfork
297and
298.Fn pdrfork
299return a PID, 0 or -1, as
300.Xr fork 2
301does.
302.Pp
303.Fn pdopenpid ,
304.Fn pdgetpid ,
305.Fn pdkill ,
306.Fn pdwait ,
307and
308.Fn pddupfd
309return 0 on success and -1 on failure.
310.Sh ERRORS
311These functions may return the same error numbers as their PID-based equivalents
312(e.g.
313.Fn pdfork
314may return the same error numbers as
315.Xr fork 2 ) ,
316with the following additions:
317.Bl -tag -width Er
318.It Bq Er EFAULT
319The copyout of the resulting file descriptor value to the memory pointed
320to by
321.Fa fdp
322failed.
323.Pp
324Note that the child process was already created when this condition
325is detected,
326and the child continues execution, same as the parent.
327If this error must be handled, it is advisable to memoize the
328.Fn getpid
329result before the call to
330.Fn pdfork
331or
332.Fn pdrfork ,
333and compare it to the value returned by
334.Fn getpid
335after, to see if code is executing in parent or child.
336.It Bq Er EINVAL
337The signal number given to
338.Fn pdkill
339is invalid.
340.It Bq Er ENOTCAPABLE
341The process descriptor being operated on has insufficient rights (e.g.
342.Dv CAP_PDKILL
343for
344.Fn pdkill ) .
345.It Bq Er EINVAL
346The
347.Fn pdwait
348function is called with reserved bits set in
349.Fa options .
350.El
351.Pp
352The
353.Fn pdopenpid
354might return the same errors as
355.Xr open 2 ,
356related to the file descriptor allocation problems, as well as the
357following specific errors:
358.Bl -tag -width Er
359.It Bq Er EINVAL
360The
361.Fa flags
362argument has reserved bits set.
363.It Bq Er ECAPMODE
364.Fn pdopenpid
365is called by the process in capability mode.
366.It Bq Er EBUSY
367The process specified by the
368.Fa pid
369argument already terminated.
370.It Bq Er ESRCH
371The process specified by the
372.Fa pid
373argument does not exist, or the caller does not have enough privileges
374to open the process.
375.It Bq Er EMFILE
376The calling process already reached its limit for open file descriptors.
377.Pp
378Current implementation installs the opened process descriptor into the
379calling process's file descriptors table.
380If the descriptor cannot be installed, the process descriptor is closed,
381which executes all actions performed by
382.Xr close 2
383on it.
384.El
385.Pp
386The
387.Fn pddupfd
388returns the following errors:
389.Bl -tag -width Er
390.It Bq Er EINVAL
391The
392.Fa flags
393argument is not zero.
394.It Bq Er EINVAL
395The file descriptor
396.Fa fd
397is not a process file descriptor.
398.It Bq Er ESRCH
399The process specified by the file descriptor
400.Fa fd
401exited.
402.It Bq Er EBADF
403The file descriptor
404.Fa remotefd
405is not a valid file descriptor in the specified process.
406.It Bq Er ENOENT
407The specified process does not have a file descriptor table.
408.It Bq Er EOPNOTSUPP
409.Fa remotefd
410refers to a file that cannot be duplicated across a process boundary,
411such as a kqueue.
412.El
413.Sh SEE ALSO
414.Xr close 2 ,
415.Xr fork 2 ,
416.Xr fstat 2 ,
417.Xr kill 2 ,
418.Xr kqueue 2 ,
419.Xr poll 2 ,
420.Xr wait4 2 ,
421.Xr capsicum 4 ,
422.Xr procdesc 4
423.Sh HISTORY
424The
425.Fn pdfork ,
426.Fn pdgetpid ,
427and
428.Fn pdkill
429system calls first appeared in
430.Fx 9.0 .
431The
432.Fn pdrfork
433and
434.Fn pdwait
435system calls first appeared in
436.Fx 15.1 .
437The
438.Fn pdopenpid
439and
440.Fn pddupfd
441system calls first appeared in
442.Fx 16.0 .
443.Pp
444Support for process descriptors mode was developed as part of the
445.Tn TrustedBSD
446Project.
447.Sh AUTHORS
448.An -nosplit
449These functions and the capability facility were created by
450.An Robert N. M. Watson Aq Mt rwatson@FreeBSD.org
451and
452.An Jonathan Anderson Aq Mt jonathan@FreeBSD.org
453at the University of Cambridge Computer Laboratory with support from a grant
454from Google, Inc.
455The
456.Fn pdrfork
457and
458.Fn pdwait
459functions were developed by
460.An Konstantin Belousov Aq Mt kib@FreeBSD.org
461with input from
462.An Alan Somers Aq Mt asomers@FreeBSD.org .
463The
464.Fn pdopenpid
465and
466.Fn pddupfd
467functions were developed by
468.An Konstantin Belousov Aq Mt kib@FreeBSD.org .
469