title: Cross-compiling of C code for Android
body: <p>I cross-compiled my C application for <em>Android ARM</em> with <em>arm-linux-gnueabi</em> tool under <em>Ubuntu 16.04 LTS</em>. I compiled it with static linking flag. This C application is big and it has complicated makefile. It compiled successfully without any errors. But it behaves <strong>differently</strong> on Android phone and Ubuntu PC. More precisely i have two problems:</p>
  
  <ol>
  <li><code>popen()</code> and <code>system()</code> functions don't work on Android. They are carried out but do nothing and don't give any errors. This problem i solved with dirty hack.</li>
  <li><code>fgets()</code> functions works strange on Android.</li>
  </ol>
  
  <p><strong>1. About first problem.</strong></p>
  
  <p>I did small research and found that Android doesn't use ordinary <em>libc</em>  library (<em>glibc</em> or another library which implements POSIX standard properly). It uses <em>Bionic</em> library instead of it (sorry, Android is new OS for me). I looked into <code>popen()</code> and <code>system()</code> functions code and noticed that these functions use <code>_PATH_BSHELL</code> macros. <code>_PATH_BSHELL</code> is path to the actual system shell. This path is "<strong>/system/bin/sh</strong>" on Android and "<strong>/bin/sh</strong>" on Ubuntu. </p>
  
  <p>When i understood it i tried to hook <code>popen()</code> and <code>system()</code> functions. I copied code of these functions from the <em>Bionic</em> source, than i defined macros <code>#define _MY_PATH_BSHELL "/system/bin/sh"</code> and replaced calls like <code>execve(_MY_PATH_BSHELL, argp, environ);</code> by <code>execve(_MY_PATH_BSHELL, argp, environ);</code> calls. So it started work properly. </p>
  
  <p><strong>2. About second problem.</strong></p>
  
  <p>On Ubuntu this code works properly:</p>
  
  <pre><code>is_received = false;
  while(!is_received) {
      FILE *cmd = popen(command, "r");
      is_received = fgets(buf, sizeof(buf), cmd) == NULL ? false : true; 
  }
  </code></pre>
  
  <p>But on Android <code>fgets()</code> always returns <code>NULL</code> and this loop works <em>infinitely long</em>. I tried to use <code>read()</code> function instead of <code>fgets()</code> and it worked.
  On Android this code with <code>read()</code> works properly:</p>
  
  <pre><code>is_received = false;
  while(!is_received) {
      FILE *cmd = hooked_popen(command, "r");
      int fd = fileno(cmd);
      is_received = read(fd, buf, sizeof(buf)) == 0 ? false : true;
  }
  </code></pre>
  
  <p><strong>My questions.</strong></p>
  
  <ol>
  <li>How to solve my problems with <code>popen()</code> and <code>system()</code> neatly and correctly? I think i have to link statically with <em>Bionic</em> library. Is it right? How can i do it in console without Android Studio? I read that it is necessary to use <em>NDK</em> but it is not clear to me how. </li>
  <li>Why <code>fgets()</code> behavior isn't similar on Android and Ubuntu?</li>
  </ol>