blob: b09e9d507f039b6f80919be77dc61e99c411fbb8 [file] [log] [blame]
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.14"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Crashpad: crashpad::ChildPortHandshake Class Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="crashpad_doxygen.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">Crashpad
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.14 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
var searchBox = new SearchBox("searchBox", "search",false,'Search');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
/* @license-end */</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<div id="nav-path" class="navpath">
<ul>
<li class="navelem"><a class="el" href="namespacecrashpad.html">crashpad</a></li><li class="navelem"><a class="el" href="classcrashpad_1_1ChildPortHandshake.html">ChildPortHandshake</a></li> </ul>
</div>
</div><!-- top -->
<div class="header">
<div class="summary">
<a href="#pub-types">Public Types</a> &#124;
<a href="#pub-methods">Public Member Functions</a> &#124;
<a href="#pub-static-methods">Static Public Member Functions</a> &#124;
<a href="#friends">Friends</a> &#124;
<a href="classcrashpad_1_1ChildPortHandshake-members.html">List of all members</a> </div>
<div class="headertitle">
<div class="title">crashpad::ChildPortHandshake Class Reference</div> </div>
</div><!--header-->
<div class="contents">
<p>Implements a handshake protocol that allows processes to exchange port rights.
<a href="classcrashpad_1_1ChildPortHandshake.html#details">More...</a></p>
<p><code>#include &quot;util/mach/child_port_handshake.h&quot;</code></p>
<table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="pub-types"></a>
Public Types</h2></td></tr>
<tr class="memitem:a727e01831df67754b0ff439735f41608"><td class="memItemLeft" align="right" valign="top">enum &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classcrashpad_1_1ChildPortHandshake.html#a727e01831df67754b0ff439735f41608">PortRightType</a> </td></tr>
<tr class="memdesc:a727e01831df67754b0ff439735f41608"><td class="mdescLeft">&#160;</td><td class="mdescRight">Controls whether a receive or send right is expected to be obtained from the client by the server’s call to <a class="el" href="classcrashpad_1_1ChildPortHandshake.html#af1400270cdc498e9c05391389e7bddad" title="Runs the server. ">RunServer()</a>. <a href="classcrashpad_1_1ChildPortHandshake.html#a727e01831df67754b0ff439735f41608">More...</a><br /></td></tr>
<tr class="separator:a727e01831df67754b0ff439735f41608"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="pub-methods"></a>
Public Member Functions</h2></td></tr>
<tr class="memitem:a9298ec6d6ba1c3ca38157322fdd0c135"><td class="memItemLeft" align="right" valign="top">base::ScopedFD&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classcrashpad_1_1ChildPortHandshake.html#a9298ec6d6ba1c3ca38157322fdd0c135">ClientReadFD</a> ()</td></tr>
<tr class="memdesc:a9298ec6d6ba1c3ca38157322fdd0c135"><td class="mdescLeft">&#160;</td><td class="mdescRight">Obtains the “read” side of the pipe, to be used by the client. <a href="#a9298ec6d6ba1c3ca38157322fdd0c135">More...</a><br /></td></tr>
<tr class="separator:a9298ec6d6ba1c3ca38157322fdd0c135"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a13c305bc7f510f7ec0696ea3257fef35"><td class="memItemLeft" align="right" valign="top">base::ScopedFD&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classcrashpad_1_1ChildPortHandshake.html#a13c305bc7f510f7ec0696ea3257fef35">ServerWriteFD</a> ()</td></tr>
<tr class="memdesc:a13c305bc7f510f7ec0696ea3257fef35"><td class="mdescLeft">&#160;</td><td class="mdescRight">Obtains the “write” side of the pipe, to be used by the server. <a href="#a13c305bc7f510f7ec0696ea3257fef35">More...</a><br /></td></tr>
<tr class="separator:a13c305bc7f510f7ec0696ea3257fef35"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:af1400270cdc498e9c05391389e7bddad"><td class="memItemLeft" align="right" valign="top">mach_port_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classcrashpad_1_1ChildPortHandshake.html#af1400270cdc498e9c05391389e7bddad">RunServer</a> (<a class="el" href="classcrashpad_1_1ChildPortHandshake.html#a727e01831df67754b0ff439735f41608">PortRightType</a> port_right_type)</td></tr>
<tr class="memdesc:af1400270cdc498e9c05391389e7bddad"><td class="mdescLeft">&#160;</td><td class="mdescRight">Runs the server. <a href="#af1400270cdc498e9c05391389e7bddad">More...</a><br /></td></tr>
<tr class="separator:af1400270cdc498e9c05391389e7bddad"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a94543dc329a5a7d869cc1cb76e23fc20"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classcrashpad_1_1ChildPortHandshake.html#a94543dc329a5a7d869cc1cb76e23fc20">RunClient</a> (mach_port_t port, mach_msg_type_name_t right_type)</td></tr>
<tr class="memdesc:a94543dc329a5a7d869cc1cb76e23fc20"><td class="mdescLeft">&#160;</td><td class="mdescRight">Runs the client. <a href="#a94543dc329a5a7d869cc1cb76e23fc20">More...</a><br /></td></tr>
<tr class="separator:a94543dc329a5a7d869cc1cb76e23fc20"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="pub-static-methods"></a>
Static Public Member Functions</h2></td></tr>
<tr class="memitem:a0f73b816d441e5e7f6650c8c5601e654"><td class="memItemLeft" align="right" valign="top">static mach_port_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classcrashpad_1_1ChildPortHandshake.html#a0f73b816d441e5e7f6650c8c5601e654">RunServerForFD</a> (base::ScopedFD server_write_fd, <a class="el" href="classcrashpad_1_1ChildPortHandshake.html#a727e01831df67754b0ff439735f41608">PortRightType</a> port_right_type)</td></tr>
<tr class="memdesc:a0f73b816d441e5e7f6650c8c5601e654"><td class="mdescLeft">&#160;</td><td class="mdescRight">Runs the server. <a href="#a0f73b816d441e5e7f6650c8c5601e654">More...</a><br /></td></tr>
<tr class="separator:a0f73b816d441e5e7f6650c8c5601e654"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a3f8c5aa2a2354ae65dcd9323554cdc2a"><td class="memItemLeft" align="right" valign="top">static bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classcrashpad_1_1ChildPortHandshake.html#a3f8c5aa2a2354ae65dcd9323554cdc2a">RunClientForFD</a> (base::ScopedFD client_read_fd, mach_port_t port, mach_msg_type_name_t right_type)</td></tr>
<tr class="memdesc:a3f8c5aa2a2354ae65dcd9323554cdc2a"><td class="mdescLeft">&#160;</td><td class="mdescRight">Runs the client. <a href="#a3f8c5aa2a2354ae65dcd9323554cdc2a">More...</a><br /></td></tr>
<tr class="separator:a3f8c5aa2a2354ae65dcd9323554cdc2a"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="friends"></a>
Friends</h2></td></tr>
<tr class="memitem:abd5035bd503394e6b1ff4ff7f50fd62a"><td class="memItemLeft" align="right" valign="top"><a id="abd5035bd503394e6b1ff4ff7f50fd62a"></a>
class&#160;</td><td class="memItemRight" valign="bottom"><b>test::ChildPortHandshakeTest</b></td></tr>
<tr class="separator:abd5035bd503394e6b1ff4ff7f50fd62a"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<div class="textblock"><p>Implements a handshake protocol that allows processes to exchange port rights. </p>
<p>Ordinarily, there is no way for parent and child processes to exchange port rights, outside of the rights that children inherit from their parents. These include task-special ports and exception ports, but all of these have system-defined uses, and cannot reliably be replaced: in a multi-threaded parent, it is impossible to temporarily change an inheritable port while maintaining a guarantee that another thread will not attempt to use it, and in children, it difficult to guarantee that nothing will attempt to use an inheritable port before it can be replaced with the correct one. This latter concern is becoming increasingly more pronounced as system libraries perform more operations that rely on an inherited port in module initializers.</p>
<p>The protocol implemented by this class involves a server that runs in one process. The server is published with the bootstrap server, which the other process has access to because the bootstrap port is one of the inherited task-special ports. The two processes also share a pipe, which the server can write to and the client can read from. The server will write a random token to this pipe, along with the name under which its service has been registered with the bootstrap server. The client can then obtain a send right to this service with <code>bootstrap_look_up()</code>, and send a check-in message containing the token value and the port right of its choice by calling <code>child_port_check_in()</code>.</p>
<p>The inclusion of the token authenticates the client to the server. This is necessary because the service is published with the bootstrap server, which opens up access to it to more than the intended client. Because the token is passed to the client by a shared pipe, it constitutes a shared secret not known by other processes that may have incidental access to the server. The <a class="el" href="classcrashpad_1_1ChildPortHandshake.html" title="Implements a handshake protocol that allows processes to exchange port rights. ">ChildPortHandshake</a> server considers its randomly-generated token valid until a client checks in with it. This mechanism is used instead of examining the request message’s audit trailer to verify the sender’s process ID because in some process architectures, it may be impossible to verify the client’s process ID.</p>
<p>The shared pipe serves another purpose: the server monitors it for an end-of-file (no readers) condition. Once detected, it will stop its blocking wait for a client to check in. This mechanism was also chosen for its ability to function properly in diverse process architectures.</p>
<p>This class can be used to allow a child process to provide its parent with a send right to its task port, in cases where it is desirable for the parent to have such access. It can also be used to allow a parent process to transfer a receive right to a child process that implements the server for that right, or for a child process to establish its own server and provide its parent with a send right to that server, for cases where a service is provided and it is undesirable or impossible to provide it via the bootstrap or launchd interfaces.</p>
<p>Example parent process, running a client that sends a receive right to its child: </p><div class="fragment"><div class="line">ChildPortHandshake child_port_handshake;</div><div class="line">base::ScopedFD server_write_fd = child_port_handshake.ServerWriteFD();</div><div class="line">std::string server_write_fd_string =</div><div class="line"> base::StringPrintf(<span class="stringliteral">&quot;%d&quot;</span>, server_write_fd.get());</div><div class="line"></div><div class="line">pid_t pid = fork();</div><div class="line"><span class="keywordflow">if</span> (pid == 0) {</div><div class="line"> <span class="comment">// Child</span></div><div class="line"></div><div class="line"> <span class="comment">// Close all file descriptors above STDERR_FILENO except for</span></div><div class="line"> <span class="comment">// server_write_fd. Let the child know what file descriptor to use for</span></div><div class="line"> <span class="comment">// server_write_fd by passing it as argv[1]. Example code for the child</span></div><div class="line"> <span class="comment">// process is below.</span></div><div class="line"> <a class="code" href="namespacecrashpad.html#a003f563ef0fe26081b4520012e0c1ef8">CloseMultipleNowOrOnExec</a>(STDERR_FILENO + 1, server_write_fd.get());</div><div class="line"> execlp(<span class="stringliteral">&quot;./child&quot;</span>, <span class="stringliteral">&quot;child&quot;</span>, server_write_fd_string.c_str(), <span class="keyword">nullptr</span>);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// Parent</span></div><div class="line"></div><div class="line"><span class="comment">// Close the child’s end of the pipe.</span></div><div class="line">server_write_fd.reset();</div><div class="line"></div><div class="line"><span class="comment">// Make a new Mach receive right.</span></div><div class="line">base::mac::ScopedMachReceiveRight</div><div class="line"> receive_right(<a class="code" href="namespacecrashpad.html#a9c9bc6ad9973f794c425707617b63278">NewMachPort</a>(MACH_PORT_RIGHT_RECEIVE));</div><div class="line"></div><div class="line"><span class="comment">// Make a send right corresponding to the receive right.</span></div><div class="line">mach_port_t send_right;</div><div class="line">mach_msg_type_name_t send_right_type;</div><div class="line">mach_port_extract_right(mach_task_self(),</div><div class="line"> receive_right.get(),</div><div class="line"> MACH_MSG_TYPE_MAKE_SEND,</div><div class="line"> &amp;send_right,</div><div class="line"> &amp;send_right_type);</div><div class="line">base::mac::ScopedMachSendRight send_right_owner(send_right);</div><div class="line"></div><div class="line"><span class="comment">// Send the receive right to the child process, retaining the send right</span></div><div class="line"><span class="comment">// for use in the parent process.</span></div><div class="line"><span class="keywordflow">if</span> (child_port_handshake.RunClient(receive_right.get(),</div><div class="line"> MACH_MSG_TYPE_MOVE_RECEIVE)) {</div><div class="line"> ignore_result(receive_right.release());</div><div class="line">}</div></div><!-- fragment --><p>Example child process, running a server that receives a receive right from its parent: </p><div class="fragment"><div class="line"><span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span>* argv[]) {</div><div class="line"> <span class="comment">// The parent passed server_write_fd in argv[1].</span></div><div class="line"> base::ScopedFD server_write_fd(atoi(argv[1]));</div><div class="line"></div><div class="line"> <span class="comment">// Obtain a receive right from the parent process.</span></div><div class="line"> base::mac::ScopedMachReceiveRight receive_right(</div><div class="line"> <a class="code" href="classcrashpad_1_1ChildPortHandshake.html#a0f73b816d441e5e7f6650c8c5601e654">ChildPortHandshake::RunServerForFD</a>(</div><div class="line"> std::move(server_write_fd),</div><div class="line"> <a class="code" href="classcrashpad_1_1ChildPortHandshake.html#a727e01831df67754b0ff439735f41608aca4dfdef124043305e6880e006032603">ChildPortHandshake::PortRightType::kReceiveRight</a>));</div><div class="line">}</div></div><!-- fragment --> </div><h2 class="groupheader">Member Enumeration Documentation</h2>
<a id="a727e01831df67754b0ff439735f41608"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a727e01831df67754b0ff439735f41608">&#9670;&nbsp;</a></span>PortRightType</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">enum <a class="el" href="classcrashpad_1_1ChildPortHandshake.html#a727e01831df67754b0ff439735f41608">crashpad::ChildPortHandshake::PortRightType</a></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">strong</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Controls whether a receive or send right is expected to be obtained from the client by the server’s call to <a class="el" href="classcrashpad_1_1ChildPortHandshake.html#af1400270cdc498e9c05391389e7bddad" title="Runs the server. ">RunServer()</a>. </p>
<table class="fieldtable">
<tr><th colspan="2">Enumerator</th></tr><tr><td class="fieldname"><a id="a727e01831df67754b0ff439735f41608aca4dfdef124043305e6880e006032603"></a>kReceiveRight&#160;</td><td class="fielddoc"><p>The server expects to receive a receive right. </p>
</td></tr>
<tr><td class="fieldname"><a id="a727e01831df67754b0ff439735f41608a765e48f6fd1bb0f18dab2cb92f6f6613"></a>kSendRight&#160;</td><td class="fielddoc"><p>The server expects to receive a send or send-once right. </p>
</td></tr>
</table>
</div>
</div>
<h2 class="groupheader">Member Function Documentation</h2>
<a id="a9298ec6d6ba1c3ca38157322fdd0c135"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a9298ec6d6ba1c3ca38157322fdd0c135">&#9670;&nbsp;</a></span>ClientReadFD()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">base::ScopedFD crashpad::ChildPortHandshake::ClientReadFD </td>
<td>(</td>
<td class="paramname"></td><td>)</td>
<td></td>
</tr>
</table>
</div><div class="memdoc">
<p>Obtains the “read” side of the pipe, to be used by the client. </p>
<p>This file descriptor must be passed to <a class="el" href="classcrashpad_1_1ChildPortHandshake.html#a3f8c5aa2a2354ae65dcd9323554cdc2a" title="Runs the client. ">RunClientForFD()</a>.</p>
<dl class="section return"><dt>Returns</dt><dd>The file descriptor that the client should read from. </dd></dl>
</div>
</div>
<a id="a94543dc329a5a7d869cc1cb76e23fc20"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a94543dc329a5a7d869cc1cb76e23fc20">&#9670;&nbsp;</a></span>RunClient()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">bool crashpad::ChildPortHandshake::RunClient </td>
<td>(</td>
<td class="paramtype">mach_port_t&#160;</td>
<td class="paramname"><em>port</em>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype">mach_msg_type_name_t&#160;</td>
<td class="paramname"><em>right_type</em>&#160;</td>
</tr>
<tr>
<td></td>
<td>)</td>
<td></td><td></td>
</tr>
</table>
</div><div class="memdoc">
<p>Runs the client. </p>
<p>This method closes the “write” side of the pipe in-process, so that the server process holds the only file descriptor that can write to the pipe. It then calls <a class="el" href="classcrashpad_1_1ChildPortHandshake.html#a3f8c5aa2a2354ae65dcd9323554cdc2a" title="Runs the client. ">RunClientForFD()</a> using the “read” side of the pipe. If <a class="el" href="classcrashpad_1_1ChildPortHandshake.html#a13c305bc7f510f7ec0696ea3257fef35" title="Obtains the “write” side of the pipe, to be used by the server. ">ServerWriteFD()</a> has already been called in the client process, the caller must ensure that the file descriptor returned by <a class="el" href="classcrashpad_1_1ChildPortHandshake.html#a13c305bc7f510f7ec0696ea3257fef35" title="Obtains the “write” side of the pipe, to be used by the server. ">ServerWriteFD()</a> is closed prior to calling this method.</p>
<dl class="section return"><dt>Returns</dt><dd><code>true</code> on success, <code>false</code> on failure with a message logged. </dd></dl>
</div>
</div>
<a id="a3f8c5aa2a2354ae65dcd9323554cdc2a"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a3f8c5aa2a2354ae65dcd9323554cdc2a">&#9670;&nbsp;</a></span>RunClientForFD()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">bool crashpad::ChildPortHandshake::RunClientForFD </td>
<td>(</td>
<td class="paramtype">base::ScopedFD&#160;</td>
<td class="paramname"><em>client_read_fd</em>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype">mach_port_t&#160;</td>
<td class="paramname"><em>port</em>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype">mach_msg_type_name_t&#160;</td>
<td class="paramname"><em>right_type</em>&#160;</td>
</tr>
<tr>
<td></td>
<td>)</td>
<td></td><td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">static</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Runs the client. </p>
<p>If a <a class="el" href="classcrashpad_1_1ChildPortHandshake.html" title="Implements a handshake protocol that allows processes to exchange port rights. ">ChildPortHandshake</a> object is available, don’t call this static function. Instead, call <a class="el" href="classcrashpad_1_1ChildPortHandshake.html#a94543dc329a5a7d869cc1cb76e23fc20" title="Runs the client. ">RunClient()</a>, which wraps this function. When using this function, the caller is responsible for ensuring that the server “write” side of the pipe is closed in the client process prior to calling this function.</p>
<p>This function performs these tasks:</p><ul>
<li>Reads the token from the pipe.</li>
<li>Reads the bootstrap service name from the pipe.</li>
<li>Obtains a send right to the server by calling <code>bootstrap_look_up()</code>.</li>
<li>Sends a check-in message to the server by calling <code>child_port_check_in()</code>, providing the token and the user-supplied port right.</li>
<li>Deallocates the send right to the server, and closes the pipe.</li>
</ul>
<p>There is no return value because <code>child_port_check_in()</code> is a MIG <code>simpleroutine</code>, and the server does not send a reply. This allows check-in to occur without blocking to wait for a reply.</p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramdir">[in]</td><td class="paramname">client_read_fd</td><td>The “read” side of the pipe shared with the server process. This function takes ownership of this file descriptor, and will close it prior to returning. </td></tr>
<tr><td class="paramdir">[in]</td><td class="paramname">port</td><td>The port right that will be passed to the server by <code>child_port_check_in()</code>. </td></tr>
<tr><td class="paramdir">[in]</td><td class="paramname">right_type</td><td>The right type to furnish the server with. If <em>port</em> is a send right, this can be <code>MACH_MSG_TYPE_COPY_SEND</code> or <code>MACH_MSG_TYPE_MOVE_SEND</code>. If <em>port</em> is a send-once right, this can be <code>MACH_MSG_TYPE_MOVE_SEND_ONCE</code>. If <em>port</em> is a receive right, this can be <code>MACH_MSG_TYPE_MAKE_SEND</code>, <code>MACH_MSG_TYPE_MAKE_SEND_ONCE</code>, or <code>MACH_MSG_TYPE_MOVE_RECEIVE</code>.</td></tr>
</table>
</dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd><code>true</code> on success, <code>false</code> on failure with a message logged. On failure, the port right corresponding to a <em>right_type</em> of <code>MACH_MSG_TYPE_MOVE_*</code> is not consumed, and the caller must dispose of the right if necessary. </dd></dl>
</div>
</div>
<a id="af1400270cdc498e9c05391389e7bddad"></a>
<h2 class="memtitle"><span class="permalink"><a href="#af1400270cdc498e9c05391389e7bddad">&#9670;&nbsp;</a></span>RunServer()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">mach_port_t crashpad::ChildPortHandshake::RunServer </td>
<td>(</td>
<td class="paramtype"><a class="el" href="classcrashpad_1_1ChildPortHandshake.html#a727e01831df67754b0ff439735f41608">PortRightType</a>&#160;</td>
<td class="paramname"><em>port_right_type</em></td><td>)</td>
<td></td>
</tr>
</table>
</div><div class="memdoc">
<p>Runs the server. </p>
<p>This method closes the “read” side of the pipe in-process, so that the client process holds the only file descriptor that can read from the pipe. It then calls <a class="el" href="classcrashpad_1_1ChildPortHandshake.html#a0f73b816d441e5e7f6650c8c5601e654" title="Runs the server. ">RunServerForFD()</a> using the “write” side of the pipe. If <a class="el" href="classcrashpad_1_1ChildPortHandshake.html#a9298ec6d6ba1c3ca38157322fdd0c135" title="Obtains the “read” side of the pipe, to be used by the client. ">ClientReadFD()</a> has already been called in the server process, the caller must ensure that the file descriptor returned by <a class="el" href="classcrashpad_1_1ChildPortHandshake.html#a9298ec6d6ba1c3ca38157322fdd0c135" title="Obtains the “read” side of the pipe, to be used by the client. ">ClientReadFD()</a> is closed prior to calling this method. </p>
</div>
</div>
<a id="a0f73b816d441e5e7f6650c8c5601e654"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a0f73b816d441e5e7f6650c8c5601e654">&#9670;&nbsp;</a></span>RunServerForFD()</h2>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">mach_port_t crashpad::ChildPortHandshake::RunServerForFD </td>
<td>(</td>
<td class="paramtype">base::ScopedFD&#160;</td>
<td class="paramname"><em>server_write_fd</em>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype"><a class="el" href="classcrashpad_1_1ChildPortHandshake.html#a727e01831df67754b0ff439735f41608">PortRightType</a>&#160;</td>
<td class="paramname"><em>port_right_type</em>&#160;</td>
</tr>
<tr>
<td></td>
<td>)</td>
<td></td><td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">static</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Runs the server. </p>
<p>If a <a class="el" href="classcrashpad_1_1ChildPortHandshake.html" title="Implements a handshake protocol that allows processes to exchange port rights. ">ChildPortHandshake</a> object is available, don’t call this static function. Instead, call <a class="el" href="classcrashpad_1_1ChildPortHandshake.html#af1400270cdc498e9c05391389e7bddad" title="Runs the server. ">RunServer()</a>, which wraps this function. When using this function, the caller is responsible for ensuring that the client “read” side of the pipe is closed in the server process prior to calling this function.</p>
<p>This function performs these tasks:</p><ul>
<li>Creates a random token and sends it via the pipe.</li>
<li>Checks its service in with the bootstrap server, and sends the name of its bootstrap service mapping via the pipe.</li>
<li>Simultaneously receives messages on its Mach server and monitors the pipe for end-of-file. This is a blocking operation.</li>
<li>When a Mach message is received, calls HandleChildPortCheckIn() to interpret and validate it, and if the message is valid, returns the port right extracted from the message. If the message is not valid, this method will continue waiting for a valid message. Valid messages are properly formatted and have the correct token. The right carried in a valid message will be returned. If a message is not valid, this method will continue waiting for pipe EOF or a valid message.</li>
<li>When notified of pipe EOF, returns <code>MACH_PORT_NULL</code>.</li>
<li>Regardless of return value, destroys the server’s receive right and closes the pipe.</li>
</ul>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramdir">[in]</td><td class="paramname">server_write_fd</td><td>The write side of the pipe shared with the client process. This function takes ownership of this file descriptor, and will close it prior to returning. </td></tr>
<tr><td class="paramdir">[in]</td><td class="paramname">port_right_type</td><td>The port right type expected to be received from the client. If the port right received from the client does not match the expected type, the received port right will be destroyed, and <code>MACH_PORT_NULL</code> will be returned.</td></tr>
</table>
</dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>On success, the port right provided by the client. The caller takes ownership of this right. On failure, <code>MACH_PORT_NULL</code>, indicating that the client did not check in properly before terminating, where termination is detected by detecting that the read side of the shared pipe has closed. On failure, a message indicating the nature of the failure will be logged. </dd></dl>
</div>
</div>
<a id="a13c305bc7f510f7ec0696ea3257fef35"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a13c305bc7f510f7ec0696ea3257fef35">&#9670;&nbsp;</a></span>ServerWriteFD()</h2>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">base::ScopedFD crashpad::ChildPortHandshake::ServerWriteFD </td>
<td>(</td>
<td class="paramname"></td><td>)</td>
<td></td>
</tr>
</table>
</div><div class="memdoc">
<p>Obtains the “write” side of the pipe, to be used by the server. </p>
<p>This file descriptor must be passed to <a class="el" href="classcrashpad_1_1ChildPortHandshake.html#a0f73b816d441e5e7f6650c8c5601e654" title="Runs the server. ">RunServerForFD()</a>.</p>
<dl class="section return"><dt>Returns</dt><dd>The file descriptor that the server should write to. </dd></dl>
</div>
</div>
<hr/>The documentation for this class was generated from the following files:<ul>
<li>util/mach/child_port_handshake.h</li>
<li>util/mach/child_port_handshake.cc</li>
</ul>
</div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.14
</small></address>
</body>
</html>