在线C编译器

时间:2011-04-14 06:35:51

标签: php c ajax

我正在做关于软件即服务的最后一年项目,“在线C编译器”是预期的服务之一。 请帮助我如何调用像GCC这样的c编译器来执行在浏览器文本区域中编写的C代码,并返回在浏览器上显示的输出。

谢谢。

5 个答案:

答案 0 :(得分:2)

轻松!只需运行许多PHP执行函数之一即可。

示例代码:

// atomic temp file with .c extension
do {
    $tmpfile = tempnam(sys_get_temp_dir(),'source');
}while(!@rename($tmpfile,$tmpfile.'.c'));

$tmpfile.='.c'; // rename succeeded, update file name
$exefile='test.exe'; // works on linux as well, linux ignores extension

file_put_contents($tmpfile,$_REQUEST['c_code']);

// invoke GCC
$output = shell_exec('gcc '.escapeshellarg($tmpfile).' -o '.escapeshellarg($exefile));
// set sticky bit
$output.= shell_exec('sudo +s '.escapeshellarg($exefile)); // I need to set this on my server
// run the created program
$output.= shell_exec(escapeshellarg($exefile));

echo '<pre>'.htmlspecialchars($output,ENT_QUOTES).'</pre>';

以上代码(虽然未经测试)应该有效。如果你想要一个更高级的流程执行例程(写STDIN,读取STDOUT和STDERR以及获取返回代码):

/**
 * Executes a program and waits for it to finish, taking pipes into account.
 * @param string $cmd Command line to execute, including any arguments.
 * @param string $input Data for standard input.
 * @return array Array of "stdout", "stderr" and "return".
 * @copyright 2011 K2F Framework / Covac Software
 */
function execute($cmd,$stdin=null){
    $proc=proc_open($cmd,array(0=>array('pipe','r'),1=>array('pipe','w'),2=>array('pipe','w')),$pipes);
    fwrite($pipes[0],$stdin);                      fclose($pipes[0]);
    $stdout=stream_get_contents($pipes[1]);        fclose($pipes[1]);
    $stderr=stream_get_contents($pipes[2]);        fclose($pipes[2]);
    $return=proc_close($proc);
    return array( 'stdout'=>$stdout, 'stderr'=>$stderr, 'return'=>$return );
}

答案 1 :(得分:1)

我认为你不想在某种容器之外执行任意代码。虽然在大多数情况下代码应该在弱势群体中运行,但您冒着以下风险:

  • 有人在你的内核中发现一个权限提升错误(想到旧的vmsplice错误)
  • 有人设置讨厌的网络服务
  • 有人向垃圾邮件的四个角投掷垃圾邮件(我从未见过它们,但我很确定互联网确实有角落)
  • 有人通过执行恼人的代码故意干扰服务器的正常使用。

我建议,鉴于您使用某种虚拟化技术来实际运行代码的潜在问题。一些候选人将是:

  • QEMU(Quick n dirty)
  • Lguest(Quick n dirty)
  • OpenVZ(有点复杂)
  • Xen半虚拟化(需要虚拟机管理程序,但非常适合您使用)

如果您的大学可以访问像Simics这样的工具,您可以使用它来代替并提供更全面的机器级调试。我不确定,因为我使用了Simics,所以它是

在这些情况下,您可以复制一个简单的操作系统,将上传的代码放入其中并执行脚本以在启动时构建,运行和收集输出。这使您可以设置有关代码运行时间的严格规则,保持运行代码的隔离并在多个体系结构上提供构建。只需将构建和程序输出定向到执行后检索的文件即可。

您还需要确保构建环境支持尽可能多的语言环境。

如果您想获得奖励积分,也可以使用Valgrind。不过,您仍然希望限制您想要处理的构建复杂程度......这样您就可以专注于使您的系统适合其广告目的的功能。

在任何一种情况下,PHP的exec() / shell_exec()系列调用都应该足以让你的前端运行一个启动其他所有内容的脚本。

答案 2 :(得分:0)

您可能会发现this项目很有用。它是一个gcc REPL(读取评估打印循环)。将它包装在某种CGI中应该能给你你想要的东西。

答案 3 :(得分:0)

您无法在浏览器中执行C代码,但您可以编写cgi程序(使用C / C ++或Perl),它可以将C代码作为输入,然后使用本地gcc编译器执行该C代码。您可以像其他任何http链接一样从浏览器中调用此cgi。最后,您必须阅读cgi的响应并在浏览器中打印响应。要了解CGI,请查看http://httpd.apache.org/docs/1.3/howto/cgi.htmlhttp://www.guyrutenberg.com/2007/08/10/introduction-to-c-cgi/

答案 4 :(得分:0)

由于您已使用PHP对其进行了标记,请参阅shell_exec函数的php手册页。您可以通过这种方式调用GCC,例如:

$command = "gcc -w -Wall -ansi -pedantic -g -o /path/to/executable /path/to/sourcefile";
$output = shell_exec($command);
echo $output;

编辑:如果不明显,你首先需要从文本区域获取并清理用户输入,将其写入文件,然后尝试编译它。