1

I've got a series of cpp source file and I want to write another program to JUDGE if they can run correctly (give input and compare their output with standart output) . so how to:

  1. call/spawn another program, and give a file to be its standard input
  2. limit the time and memory of the child process (maybe setrlimit thing? is there any examples?)
  3. donot let the process to read/write any file
  4. use a file to be its standard output
  5. compare the output with the standard output.

I think the 2nd and 3rd are the core part of this prob. Is there any way to do this?

ps. system is Linux

NamiW
  • 1,572
  • 4
  • 19
  • 33
  • 4
    You can probably do all that with a shell script, no need to beat yourself up with C++ to get the job done. `./program output.txt; if cmp output.txt known-good.txt; then echo "yay"; fi` – Greg Hewgill Mar 22 '12 at 01:57
  • Each of your bullet points should be a different question. You're asking too many different things at once. – mfontanini Mar 22 '12 at 01:58
  • is there any examples for this? how can I limit resources of process using shell script? – NamiW Mar 22 '12 at 01:59
  • 2
    see the docs for `ulimit` for how to limit resource consumption. – Greg Hewgill Mar 22 '12 at 02:00
  • possible duplicate of [Grading Program - Compile/executing c++ code within c++](http://stackoverflow.com/questions/5131085/grading-program-compile-executing-c-code-within-c) and [How to prevent some api being invoked in a source code?](http://stackoverflow.com/q/6535500/103167) and [Organizing Programming Contest - Howto compile and execute](http://stackoverflow.com/q/5372939/103167) and [What harm can a C/asm program do to Linux when run by an unprivileged user?](http://stackoverflow.com/q/9506596/103167) – Ben Voigt Mar 22 '12 at 02:48

3 Answers3

2

To do this right, you probably want to spawn the child program with fork, not system.

This allows you to do a few things. First of all, you can set up some pipes to the parent process so the parent can supply the input to the child, and capture the output from the child to compare to the expected result.

Second, it will let you call seteuid (or one of its close relatives like setreuid) to set the child process to run under a (very) limited user account, to prevent it from writing to files. When fork returns in the parent, you'll want to call setrlimit to limit the child's CPU usage.

Just to be clear: rather than directing the child's output to a file, then comparing that to the expected output, I'd capture the child's output directly via a pipe to the parent. From there the parent can write the data to a file if desired, but can also compare the output directly to what's expected, without going through a file.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
1
std::string command = "/bin/local/app < my_input.txt > my_output_file.txt 2> my_error_file.txt";
int rv = std::system( command.c_str() );
01100110
  • 2,294
  • 3
  • 23
  • 32
  • 1
    You changed the question after my answer. "donot let the process to read/write any file" conflicts with "use a file to be its standard output" and " give a file to be its standard input". That's reading and writing files. – 01100110 Mar 22 '12 at 02:07
0

1) The system function from the STL allows you to execute a program (basically as if invoked from a shell). Note that this approach is inherenly insecure, so only use it in a trusted environment.
2) You will need to use threads to be able to achieve this. There are a number of thread libraries available for C++, but I cannot give you recommendation.
[After edit in OP's post]
3) This one is harder. You either have to write a wrapper that monitors read/write access to files or do some Linux/Unix privilege magic to prevent it from accessing files.
4) You can redirect the output of a program (that it thinks goes to the standard output) by adding > outFile.txt after the way you would normally invoke the program (see 1)) -- e.g. otherapp > out.txt
5) You could run diff on the saved file (from 3)) to the "golden standard"/expected output captured in another file. Or use some other method that better fits your need (for example you don't care about certain formatting as long as the "content" is there). -- This part is really dependent on your needs. diff does a basic comparing job well.

Attila
  • 28,265
  • 3
  • 46
  • 55