3

I want to create an online compiler of C/C++.

Till now I have developed the following code:

<?php
error_reporting(E_ALL);
if ($_FILES["file"]["error"] > 0)
{
echo "Return Code: " . $_FILES["file"]["error"] . "<br />";
}
else
{


    move_uploaded_file($_FILES["file"]["tmp_name"],$_FILES["file"]["name"]);
    compile();
}
function compile()
{
$a=shell_exec('gcc -o Compile Compile.c');
echo $a;
$b=shell_exec('./Compile');
echo $b;
}
?>

The file Compile.c is getting uploaded and after that compiled by gcc. What I want to do is:

  • Read error from stderr when compilation results in error and display on webpage.
  • If no error then execute the code on an input file and display time of execution, if time exceeds a particular value, then show time limit exceeded error.

I searched internet and found that if compilation statement is appended by "2>&1" as

$a=shell_exec('gcc -o Compile Compile.c 2>&1');

Then the output of compilation error is returned to assigned variable($a in above case), but not without it. So my problem is how to check for error and then display it on webpage without appending "2>&1" and if no error, then carry out second step given above .

aknosis
  • 3,602
  • 20
  • 33
Shashwat Kumar
  • 5,159
  • 2
  • 30
  • 66

2 Answers2

6

The correct use of proc_open() would look like this:

$process = proc_open('gcc -o Compile Compile.c', array(
    0 => array('pipe', 'r'), // STDIN
    1 => array('pipe', 'w'), // STDOUT
    2 => array('pipe', 'w')  // STDERR
), $pipes);

if(is_resource($process)) {
    // If you want to write to STDIN
    fwrite($pipes[0], '...');
    fclose($pipes[0]);

    $stdOut = stream_get_contents($pipes[1]);
    fclose($pipes[1]);

    $stdErr = stream_get_contents($pipes[2]);
    fclose($pipes[2]);

    $returnCode = proc_close($process);
}

This would execute the shell command and give you detailed control of STDIN, STDOUT and STDERR.

Thomas Bachem
  • 1,545
  • 1
  • 16
  • 10
0

PHP contains a plethora of functions for executing external processes, each with it's own set of defiencies.

In this particular case, you might be able to hold on to some simplicity by using exec (and redirecting stderr to stdout with 2>&1). The return value, although a string, is useless; it's only the last line of the output; however, the second argument ought to be an array that is filled with the output (an entry per line), and the third argument, return_var will tell you whether the compilation succeeded or not: 0 means success, anything else a failure.

eq-
  • 9,986
  • 36
  • 38