Search code examples
phpcexecshared-hostingpow

C function pow() won't execute in shared hosting server


I'm trying to run a C program through PHP exec() function. All is running well in my localhost machine, but when running it in hosting server, C program with pow() function that have variables as argument just won't execute.

I asked the customer support of that hosting, they said that executing C programming language is not supported on their server.

But what is strange for me is, why is my another C program is running well on that server, it just that one code that has pow() with variable as parameter in it that won't run.

Here is my code:

PHP

public function index() {
  //runs well
  $varExec = exec(app_path() . "/Exec/checkfuncpow.exe");
  var_dump($varExec);
  echo "<br/>";
  //this the one that is not running
  $varExec = exec(app_path() . "/Exec/checkfuncpowwithvar.exe");
  var_dump($varExec);
}

Results:

string(8) "9.000000"

string(0) ""

checkfuncpow.c

#include <stdio.h>
#include <math.h>

int main() {
  printf("%f", pow((double)3, (double)2));
  return 0;
}

checkfuncpowwithvar.c

#include <stdio.h>
#include <math.h>

int main() {
  double param = 3;
  printf("%f", pow(param, (double)2));
  return 0;
}

Both code was compiled with the mandatory -lm flag to link to math library

gcc checkfuncpow.c -o ./Exec/checkfuncpow.exe -lm
gcc checkfuncpowwithvar.c -o ./Exec/checkfuncpowwithvar.exe -lm

So the ultimate question is is that really because the server does not support it? Or it should be able to run but the customer support didn't have a clue about the problem , so they just saying what is easy for them?


Solution

  • The canonical answer: if your hosting service doesn't support executing C programs, then you should not do it; first of all, because programs may have bugs or strange behavior (like in this case), and second, because the hosting service would not give you any support in case of problems (like in this case).

    The interesting answer: the mystery that is going through here is probably related to two things: 1) compiler optimization; 2) missing math library.

    About compiler optimization, your two programs happen to behave differently because in the first case (no param variable), the compiler replaces pow((double)3, (double)2) with (double) 9.0; therefore there is no call to pow(), and a math library is not necessary. In the second case, the compiler doesn't optimize the pow() call away, so a math library is still necessary. If my guess is correct, and you compile both your programs with gcc option -O3, both programs should now run without problems.

    About missing math library: the math library is linked to your program dynamically (with -lm option); that means that the target platform where the program will run needs to have the library installed. On the other hand, statically-linked libraries get embedded in your program so that the target platform is not required to have them installed.

    One thing you could try is to statically link the math library (libm). Search about the topic if you don't know how to do it.

    EDIT: in order to solve the problem statically-linking libraries into your executable, you can have a look at this StackOverflow question. TL;DR: GCC option -static should tell the compiler to use static libraries instead of dynamic ones, as long as static version of the library is available. In the case of libm, on my Ubuntu 20.04 box, static version of libm is available, so if I compile a program with command gcc -o program main.c -lm -static, GCC successfully use static version of libm.