⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 living_without_forks.html

📁 ADI 公司blackfin系列的用户使用文挡。
💻 HTML
📖 第 1 页 / 共 2 页
字号:
                        <span class="kw1">while</span> <span class="br0">&#40;</span><span class="br0">&#40;</span>wpid = wait<span class="br0">&#40;</span>&amp;stat<span class="br0">&#41;</span><span class="br0">&#41;</span> != pid<span class="br0">&#41;</span>                                <span class="kw1">if</span> <span class="br0">&#40;</span>wpid == <span class="nu0">-1</span> &amp;&amp; errno == ECHILD<span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="coMULTI">/* see wait(2) manpage */</span>                                        stat = <span class="nu0">0</span>;                                        <span class="kw2">break</span>;                                <span class="br0">&#125;</span>                <span class="br0">&#125;</span>        <span class="br0">&#125;</span> <span class="kw1">else</span> <span class="kw1">if</span><span class="br0">&#40;</span>pid &lt; <span class="nu0">0</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>    <span class="co1">// error in vfork caught here</span>                err<span class="br0">&#40;</span><span class="st0">"fork of rc shell failed<span class="es0">\n</span>"</span><span class="br0">&#41;</span>;                stat = <span class="nu0">-1</span>;        <span class="br0">&#125;</span>        st = WEXITSTATUS<span class="br0">&#40;</span>stat<span class="br0">&#41;</span>;        <span class="kw1">return</span> st;<span class="br0">&#125;</span>&nbsp;</pre><p>The <strong>inetd</strong> internet daemon is given the task of monitoring a number of internet sockets and waiting ofr a connection on one of them. When a connection is established the daemon has to fork a new process to handle the connection. The <strong>/etc/inetd.conf</strong> file contains details of the ports to be monotired and the programs used to handle incoming connections.</p><p> Example /etc/inetd.conf file </p><pre class="code"></pre><p>Having extablished a connection attepmt on a designated port the daemon is required to  start executing the handler task for that connection. The complication here is that the child has to have the incoming socket as its <strong>stdin</strong> and <strong>stdout</strong> devices.</p><p>The incoming port (<strong>fd</strong> in this case ) is transferred to <strong>stdin</strong> and <strong>stdout</strong> of the new task after the vfork.</p><p>Here is a code example showing this.</p><pre class="code c">&nbsp;<span class="co1">// here fd is the incoming socket</span><span class="kw4">static</span> pid_tstart_child<span class="br0">&#40;</span><span class="kw4">struct</span> stService *p, <span class="kw4">int</span> fd<span class="br0">&#41;</span><span class="br0">&#123;</span>        pid_t   pid;&nbsp;        pid = vfork<span class="br0">&#40;</span><span class="br0">&#41;</span>;&nbsp;        <span class="kw1">if</span> <span class="br0">&#40;</span>pid == <span class="nu0">0</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>                <span class="co1">// if we are the child</span>                <span class="kw1">if</span> <span class="br0">&#40;</span>fd != <span class="nu0">0</span><span class="br0">&#41;</span>                        dup2<span class="br0">&#40;</span>fd, <span class="nu0">0</span><span class="br0">&#41;</span>;  <span class="co1">// fd becomes stdin</span>                <span class="kw1">if</span> <span class="br0">&#40;</span>fd != <span class="nu0">1</span><span class="br0">&#41;</span>                        dup2<span class="br0">&#40;</span>fd, <span class="nu0">1</span><span class="br0">&#41;</span>;  <span class="co1">// fd becomes stdout</span>                <span class="kw1">if</span> <span class="br0">&#40;</span>fd != <span class="nu0">2</span><span class="br0">&#41;</span>                        dup2<span class="br0">&#40;</span>fd, <span class="nu0">2</span><span class="br0">&#41;</span>;  <span class="co1">// fd becomes stderr</span>                <span class="kw1">if</span> <span class="br0">&#40;</span>fd &gt; <span class="nu0">2</span><span class="br0">&#41;</span>                        close<span class="br0">&#40;</span>fd<span class="br0">&#41;</span>;    <span class="co1">// now we can close it (the dups stay open)</span>                close_all_fds<span class="br0">&#40;</span><span class="nu0">2</span><span class="br0">&#41;</span>;                execlp<span class="br0">&#40;</span>p-&gt;args<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>,    <span class="co1">// run the new program with fd as stdin etc</span>                                p-&gt;args<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>,                                p-&gt;args<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span>,                                p-&gt;args<span class="br0">&#91;</span><span class="nu0">2</span><span class="br0">&#93;</span>,                                p-&gt;args<span class="br0">&#91;</span><span class="nu0">3</span><span class="br0">&#93;</span>,                                p-&gt;args<span class="br0">&#91;</span><span class="nu0">4</span><span class="br0">&#93;</span>,                                p-&gt;args<span class="br0">&#91;</span><span class="nu0">5</span><span class="br0">&#93;</span>,                                <span class="kw2">NULL</span>                                <span class="br0">&#41;</span>;                _exit<span class="br0">&#40;</span><span class="nu0">0</span><span class="br0">&#41;</span>;           <span class="br0">&#125;</span>        <span class="kw1">return</span><span class="br0">&#40;</span>pid<span class="br0">&#41;</span>;  <span class="co1">// back to the parent here</span><span class="br0">&#125;</span>&nbsp;</pre></div><!-- SECTION [2106-6533] --><h3><a name="webservers" id="webservers">Webservers</a></h3><div class="level3"><p> A webserver is another example of a process needing to use forks. Each incoming socket is normally passed to a forked clone of the parent.</p><p>Consider this code from <strong>cgi.c</strong> ( in directory <strong>user/boa/src</strong> ). Here the switch to <strong>MMUless</strong> is quite painless.  </p><pre class="code c">&nbsp;<span class="co1">// either fork or vfork will do here </span>&nbsp;<span class="co2">#if HAVE_FORK</span>    child_pid = fork<span class="br0">&#40;</span><span class="br0">&#41;</span>;<span class="co2">#else</span>    child_pid = vfork<span class="br0">&#40;</span><span class="br0">&#41;</span>;<span class="co2">#endif</span>&nbsp;&nbsp;</pre><p>Consider this code from <strong>thttpd.c</strong> ( in directory <strong>user/thttpd/</strong> ) which shows the modification made to the MMUfull version of this code to make it run as a foreground process , skipping the <strong>daemonize</strong> fork</p><pre class="code c">&nbsp;&nbsp;       */<span class="co2">#ifndef EMBED</span>        <span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span> fclose<span class="br0">&#40;</span> stdin <span class="br0">&#41;</span>;        <span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span> fclose<span class="br0">&#40;</span> stdout <span class="br0">&#41;</span>;        <span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span> fclose<span class="br0">&#40;</span> stderr <span class="br0">&#41;</span>;&nbsp;        <span class="coMULTI">/* Daemonize - make ourselves a subprocess. */</span>        <span class="kw1">switch</span> <span class="br0">&#40;</span> fork<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#41;</span>            <span class="br0">&#123;</span>            <span class="kw1">case</span> <span class="nu0">0</span>:            <span class="kw2">break</span>;            <span class="kw1">case</span> <span class="nu0">-1</span>:            syslog<span class="br0">&#40;</span> LOG_CRIT, <span class="st0">"fork - %m"</span> <span class="br0">&#41;</span>;            exit<span class="br0">&#40;</span> <span class="nu0">1</span> <span class="br0">&#41;</span>;            <span class="kw1">default</span>:            exit<span class="br0">&#40;</span> <span class="nu0">0</span> <span class="br0">&#41;</span>;            <span class="br0">&#125;</span><span class="co2">#endif</span></pre></div><!-- SECTION [6534-7605] --><h3><a name="stubborn_cases" id="stubborn_cases">Stubborn Cases</a></h3><div class="level3"><p> There are a few. You have to fork and you origianlly ( in MMUfull world) wanted an exact copy of yourself.</p><p>These are the problem cases. Normally you can save important data in environment variables  and then restart yourself in a call to <strong>execve</strong> using a command line argument to select the <strong>child</strong> mode of operation.</p><p>The new child task will detect that it is functioning in <strong>child</strong> mode and restore the needed data from environment variables and continue.</p></div><!-- SECTION [7606-] --></body></html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -