    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: Donâ€™t Assume Any Non-Zero exit() Will Fail!</title>
        <link>https://members.accu.org/index.php/articles/2522</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>




<div class="xar-mod-head"><span class="xar-mod-title">Programming Topics + CVu Journal Vol 30, #3 - July 2018</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c65/">Programming</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c77/">CVu</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c387/">303</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/c65-387/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/articles/c65+387/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;Donâ€™t Assume Any Non-Zero exit() Will Fail!</h1>
<p><strong>Author:</strong>&nbsp;Bob Schmidt</p>
<p>
<strong>Date:</strong> 06 July 2018 17:13:44 +01:00 or Fri, 06 July 2018 17:13:44 +01:00</p>
<p><strong>Summary:</strong>&nbsp;Silas S. Brown shares his finding on process exit codes.</p>
<p><strong>Body:</strong>&nbsp;<p>I  recently came across a little â€˜gotchaâ€™ on a BSD system which also affects GNU/Linux systems. I was using <code>make</code> to run a series of commands including a Python script, and I assumed that <code>make</code> would stop if the Python script exitted with non-zero status. In the Python script I had done <code>os.system()</code> to run a shell command, and, if the result is non-zero, then <code>sys.exit()</code> with that result to fail the Python script as well:</p>

<pre class="programlisting">
  err = os.system(&quot;...&quot;)
  if err: sys.exit(err) # DON'T DO THIS!</pre>
  
<p>Except <code>make</code> carried on regardless. It didn't stop at the failure.</p>

<p>It turned out that <code>os.system()</code> was returning 256. And in the <code>bash</code> shell on both BSD and Linux, the command:</p>

<pre class="programlisting">
 python -c 'import sys; sys.exit(256)' || echo fail</pre>
 
<p>prints nothing.</p>

<p>The POSIX standard <code>wait()</code> and <code>waitpid()</code> calls provide only the lowest 8 bits of the exit status in <code>WEXITSTATUS</code>, so an exit status of 256 would be read as 0. The newer <code>waitid()</code> call returns 32 bits of exit status, but obviously not all system tools use it. (The underlying C standard defines only <code>EXIT_SUCCESS</code> and <code>EXIT_FAILURE</code> as 0 and 1; it says nothing about how platforms treat other values.)</p>

<p>But why was <code>os.system</code> returning 256 in the first place? As can be seen from:</p>

<pre class="programlisting">
  &gt;&gt;&gt; import os
  &gt;&gt;&gt; os.system(&quot;exit 3&quot;)
  768</pre>
  
<p>the return value of <code>os.system() </code>is not (on Unix/Linux) the straightforward exit code of the program it called. So we turn to the Python docs:</p>

<p class="blockquote">On Unix, the return value [of <code>os.system()</code>] is the exit status of the process encoded in the format specified for <code>wait()</code></p>

<p>which links to a page saying:</p>

<p class="blockquote">exit status indication: a 16-bit number, whose low byte is the signal number that killed the process, and whose high byte is the exit status (if the signal number is zero); the high bit of the low byte is set if a core file was produced.</p>

<p>Incidentally the man page of the underlying C <code>system()</code> function on BSD also says, â€œ<p class="blockquote">The system() function returns the exit status of the shell as returned by </p>
<code>waitpid(2)</code>â€ which says youâ€™re supposed to call <code>WEXITSTATUS</code> to get the exit status from it if <code>WIFEXITED</code> is true.</p>

<p>So to be more portable, you have to do something like:</p>

<pre class="programlisting">
  if (err &amp; 0xFF) == 0: err &gt;&gt;= 8
  sys.exit(err)</pre>
  
<p>or check what platform youâ€™re on and act accordingly.</p>

<p>On Windows, <code>os.system()</code> straightforwardly returns the exit code of the command interpreter. But not all Windows command shells actually pass on the exit code of the program they ran. <span class="filename">cmd.exe</span> does, but the older <span class="filename">command.com</span> on Win9x systems didnâ€™t, and more worryingly third-party â€˜power shellsâ€™ and such are not guaranteed to (the Python docs say check their documentation). So the only way you can guarantee to find out the real exit code is to run the program directly with <code>os.spawn*</code>, or use the (new in Python 2.4) <code>subprocess</code> module, instead of using a system shell.</p>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
