Let me work thru a typical capability transaction ...
Steps that we will suggest are seldom thought necessary in classic (Unix) systems, but perhaps this is largely due to their substantial cost there.
Component B invokes C which runs in another address space. Unix provides several ways of doing this: pipes, exec, and some Unixes have custom means: Solaris has its undocumented “doors” and Linux has “clone”.
B has created about a megabyte of data, X, that C must read to produce about a kilobyte of data to return to B. C will invoke other components unknown to B in this task. The convention between B and C is that B will dispose of the storage holding the response when it is done with it.
In either system we must decide what steps are necessary for B to have access to C. I shall assume in this case that the invocation of C is not to interact with others who invoke C; in effect C is free of side-effects.
It comes time to invoke C. B invokes the segment capability S to obtain a read-only capability, R, to the same segment. B “calls” a capability to C passing R. C installs the received capability in its own address space in order to read the data. C creates a segment for the response and installs that segment at another address. C finds from the data that yet another consultant is required for the job and passes R to that sub-sub contractor. The response in this case is an integer which is returned by value. C resumes its work and produces the data required by B. C returns to B passing the segment with the answer. B maps the segment with the response and uses the answer. B then invokes the returned segment to delete it. It may also invoke S to delete it if it is done with S too.
The scenario ends here.