title: mod_perl odd behaviour with system() or exec() call or backticks
body: <p>I developped a simple script in Perl that let's me verify if USB key is mounted or not and eventually unmount it.</p>
  
  <p>I am not sure if problem is related to programming or configuration, if I was wrong let me know and I will repost my question on server configuration related stack.</p>
  
  <p>Basic issue is:
  When I execute those scripts in terminal using <code>Perl</code> it works perfectly fine, althou when I do it in the browser using <code>mod_perl</code> it shows some pretty odd behaviour.</p>
  
  <h1>Sources</h1>
  
  <h2>panelmin.pl</h2>
  
  <p>This program simply outputs a message that indicates if the system device <code>/dev/sda1</code> is mounted in the system.</p>
  
  <pre><code>#!/usr/bin/perl
  use strict;
  use warnings;
  
  print "Content-type:text/html\n\n";
  print "&lt;html&gt;&lt;head&gt;&lt;title&gt;USB test&lt;/title&gt;";
  print "&lt;/head&gt;&lt;body&gt;";
  
  my $mounted = `df -h | grep /dev/sda1`;
  
  if ($mounted eq '') {
          print '&lt;h1&gt;USB device not connected&lt;/h1&gt;';
          print $mounted;
  }
  else {
          print '&lt;h1&gt;Device is connected&lt;/h1&gt;';
  }
  print '&lt;/body&gt;&lt;/html&gt;';
  </code></pre>
  
  <h2>umount.pl</h2>
  
  <p>This program umounts the <code>/dev/sda1</code> device from the system.</p>
  
  <pre><code>#!/usr/bin/perl
  print "Content-type:text/html\n\n";
  print "&lt;html&gt;&lt;head&gt;&lt;title&gt;Umount&lt;/title&gt;&lt;/head&gt;&lt;body&gt;";
  system("sudo", "umount", "/dev/sda1");
  print "&lt;/body&gt;&lt;/html&gt;";
  </code></pre>
  
  <h1>Test scenario</h1>
  
  <ol>
  <li><p>Manually mounting the device <code>/dev/sda1</code>, (it is declared in <code>fstab</code>):</p>
  
  <pre><code>$ mount -a
  </code></pre>
  
  <p>Making sure the device is mounted in the system:</p>
  
  <pre><code>$ mount
  /dev/sda1 on /mnt/usbstick type vfat (rw,relatime,uid=1000,gid=1000,fmask=0137,dmask=0027,codepage=437,iocharset=ascii,shortname=mixed,utf8,errors=remount-ro)
  </code></pre></li>
  <li><p>Executing <code>panelmin.pl</code> in the web browser (I will use curl for the purpose of clean output):</p>
  
  <pre><code>$ curl http://localhost/cgi-bin/admin/Q/panel/panelmin.pl
  &lt;html&gt;&lt;head&gt;&lt;title&gt;USB test&lt;/title&gt;&lt;/head&gt;&lt;body&gt;&lt;h1&gt;Device is connected&lt;/h1&gt;&lt;/body&gt;&lt;/html&gt;
  </code></pre>
  
  <p>As we can see, the output is correct. It detected the through linux command <code>df -h</code> that the device <code>/dev/sda1</code> is mounted in the system.</p></li>
  <li><p>Executing <code>umount.pl</code> in the web browser in order to umount the device:</p>
  
  <pre><code>$ curl http://localhost/cgi-bin/admin/Q/panel/umount.pl
  &lt;html&gt;&lt;head&gt;&lt;title&gt;Umount&lt;/title&gt;&lt;/head&gt;&lt;body&gt;&lt;/body&gt;&lt;/html&gt;
  </code></pre></li>
  <li><p>Verifying if the device is umounted using both <code>panelmin.pl</code> script in the web browser and linux command line.</p>
  
  <pre><code>$ curl http://localhost/cgi-bin/admin/Q/panel/panelmin.pl
  &lt;html&gt;&lt;head&gt;&lt;title&gt;USB test&lt;/title&gt;&lt;/head&gt;&lt;body&gt;&lt;h1&gt;USB device not connected&lt;/h1&gt;&lt;/body&gt;&lt;/html&gt;
  </code></pre>
  
  <p>Seems to be correct, but let's verify it manually with <code>df -h</code> command:</p>
  
  <pre><code>$ df -h | grep /dev/sda1
  /dev/sda1        15G  366M   15G   3% /mnt/usbstick
  </code></pre>
  
  <p>As we can see the device is still mounted in the system.</p></li>
  <li><p>Let's retry the whole process but this time instead of executing scripts in the browser we will launch them manually with <code>Perl</code> in the terminal. First lets umount the device. This will also show that the user is in sudoers and script can umount it.</p>
  
  <pre><code>$ sudo umount /dev/sda1
  $ df -h | grep /dev/sda1
  </code></pre>
  
  <p>Let's repeat the process.</p>
  
  <pre><code>$ mount -a (as superuser)
  $ df -h | grep /dev/sda1
  /dev/sda1        15G  366M   15G   3% /mnt/usbstick
  </code></pre>
  
  <p>And finally the test:</p>
  
  <pre><code>$ perl panelmin.pl 
  Content-type:text/html
  &lt;html&gt;&lt;head&gt;&lt;title&gt;USB test&lt;/title&gt;&lt;/head&gt;&lt;body&gt;&lt;h1&gt;Device is connected&lt;/h1&gt;&lt;/body&gt;
  
  $ perl umount.pl 
  Content-type:text/html
  &lt;html&gt;&lt;head&gt;&lt;title&gt;Umount&lt;/title&gt;&lt;/head&gt;&lt;body&gt;&lt;/body&gt;&lt;/html&gt;
  
  $ perl panelmin.pl 
  Content-type:text/html
  &lt;html&gt;&lt;head&gt;&lt;title&gt;USB test&lt;/title&gt;&lt;/head&gt;&lt;body&gt;&lt;h1&gt;USB device not connected&lt;/h1&gt;&lt;/body&gt;&lt;/html&gt;
  
  $ df -h | grep /dev/sda1
  </code></pre>
  
  <p>Now <code>df -h | grep /dev/sda1</code> returned empty string, it has proven that <code>umount.pl</code> managed to umount the device from the system, but only if executed in the shell with <code>Perl</code>.</p></li>
  </ol>
  
  <h1>Attempts to solve the issue</h1>
  
  <ol>
  <li><p>Making sure the user who executes <code>sudo umount /dev/sda1</code> in <code>umount.pl</code> has right to do so, I verified it by executing <code>whoami</code> inside the script and printing it in the output.</p></li>
  <li><p>Trying different syntax of <code>system()</code>, for example separating the arguments or executing it all as one command.</p></li>
  <li><p>I verified if my mod_perl executes scripts in <code>taint mode</code>, because I heard it may influence executing external processes. As a matter of fact in my <code>httpd.conf</code> there is no <code>PerlTaintCheck On</code> and if I understand it correctly, it would influence the execution with dynamic arguments (for security reasons), in case of my script it is same command each time.</p></li>
  <li><p>I tryed to use different functions, replace <code>System</code> by <code>Exec</code> or by backticks etc.</p></li>
  <li><p>I tryed to use <code>Apache2::SubProcess</code>, just like they do it <a href="http://search.cpan.org/dist/mod_perl/docs/api/Apache2/SubProcess.pod" rel="nofollow">here</a> , but I must admit I'm not sure if I did it correctly, I'm new to Perl and this (and all other available on net) example is just horrible, for example <code>$r</code> variable is never initiated in their code, I just declarated it as <code>Apache2::RequestRec object</code>, it didn't work.</p></li>
  <li><p>I tryed to change env variables like they explained <a href="http://docstore.mik.ua/orelly/weblinux2/modperl/ch10_02.htm" rel="nofollow">here</a> in subsection <code>10.2.6. Starting a Long-Running External Program</code></p></li>
  <li><p>I verified the logs in Apache directory, have found errors but not related to those scripts, I didn't post them here because I didn't wanted it to bee too messy.</p></li>
  </ol>
  
  <h1>Interpretation</h1>
  
  <p>The fact it works with <code>Perl</code> and not with <code>mod_perl</code> is not that surprising, what I find the most strange is with <code>mod_perl</code> the script <code>panelmin.pl</code> seems to works fine with it's <code>system()</code> launch and suddenly after executing <code>umount.pl</code> it does not work correctly anymore. For now I am out of ideas, I find this behaviour odd and I count on you guys. I hope someone knows what should I do. Thanks.</p>
  
  <h1>Requested results</h1>
  
  <ol>
  <li><p>Capturing the output of System in <code>umount.pl</code>.</p>
  
  <pre><code>#!/usr/bin/perl
  print "Content-type:text/html\n\n";
  print "&lt;html&gt;&lt;head&gt;&lt;title&gt;Umount&lt;/title&gt;&lt;/head&gt;&lt;body&gt;";
  my $res = `sudo umount /dev/sda1`;
  print "$res&lt;/body&gt;&lt;/html&gt;";
  </code></pre>
  
  <p>And the result is void:</p>
  
  <pre><code>$ curl http://localhost/cgi-bin/admin/Q/panel/umount.pl
  &lt;html&gt;&lt;head&gt;&lt;title&gt;Umount&lt;/title&gt;&lt;/head&gt;&lt;body&gt;&lt;/body&gt;&lt;/html&gt;
  </code></pre></li>
  </ol>