Sabo is the Revolutionary Army's Chief of Staff, recognized as the "No. 2" of the > entire organization, ranking directly under Monkey D. Dragon himself.[2] Next to > being the sworn brother of Monkey D. Luffy and Portgas D. Ace, he is of noble > descent, the son of Outlook III, as well as via his parents the adopted brother of Stelly, the current king of the Goa Kingdom, whom Sabo has never recognized as such.
#include "sabo_core.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
void
judge()
{
sabo_ctx_t ctx;
sabo_res_t res;
const char *err, *judge_flag;
ctx.user_out_fd = open("/path/to/user.out", O_WRONLY);
if (ctx.user_out_fd < 0) {
fprintf(stderr, "failed to open user.out: %s\n", strerror(errno));
return;
}
ctx.data_in_fd = open("/path/to/data.in", O_RDONLY);
if (ctx.data_in_fd < 0) {
fprintf(stderr, "failed to open user.out: %s\n", strerror(errno));
return;
}
ctx.executor = "/path/to/Main"; /* Main is an ELF format file which can be executed */
ctx.code_bin_file = "Main";
ctx.time_limits = 1000;
ctx.memory_limits = 65536;
ctx.language = SABO_C_CPP; /* use ptrace to monitor the user process */
ctx.classpath = NULL; /* only for java */
/*
* or for java
* ctx.executor = "/path/to/java/bin/java";
* ctx.code_bin_file = "Main";
* ctx.language = SABO_JAVA
* ctx.classpath = "path/to/classfile/"
*/
err = sabo_core_run(&ctx, &res);
if (err) {
fprintf(stderr, "failed to run user code: %s\n", err);
return;
}
switch (res.judge_flag) {
case SABO_DONE:
judge_flag = "done";
break;
case SABO_TLE:
judge_flag = "TLE";
break;
case SABO_MLE:
judge_flag = "MLE";
break;
case SABO_RE:
judge_flag = "RE";
break;
case SABO_RE_DBZ:
judge_flag = "RE(FPE)";
break;
case SABO_MC:
judge_flag = "MC";
break;
default:
judge_flag = "SYSERR";
break;
}
fprintf(stdout, "judge flag: %s time_used: %d, memory_used: %d\n",
judge_flag, res.time_used, res.memory_used);
}
You need to compile the libsabocore code with make
and you will get libsacore.a
and libsabocore.so
.
libsabocore
is an ACM/ICPC judger core lib in ANSI C.
One can use libsabocore
with packaging it under any languages, such as my another program sabo, they are not twin(the latter's core interface is ugly and is internal) but the principle is same(ptrace).
The only thing you need to care is the structure sabo_ctx_t
and sabo_res_t
, the former is the container that you pass the needed args to libsabocore
, and you can get result from the latter.
Now, let's see both of them and the interface.
typedef struct {
const char *code_bin_file;
const char *executor;
int data_in_fd;
int user_out_fd;
int time_limits;
int memory_limits;
int language; /* FIXME, just for java now */
const char *classpath; /* FIXME, for java class path */
} sabo_ctx_t;
item | meaning |
---|---|
code_bin_file |
the file name of the code(compiled) |
executor |
the code interpreter(full name) for java, executor is the java binary path(/path/to/java), for C/C++, executor is the ELF file path(/path/to/a.out) |
data_in_fd |
the file descriptor of data.in |
user_out_fd |
the file descriptor of user.out |
time_limits |
the time resource limit of your process |
memory_limits |
the memory resource limit of your process |
language |
Choose SABO_JAVA or SABO_C_CPP based on your program |
classpath |
used for java, you need to set an appropriate path where you hope java will find class in there |
For the meaning of `language`, you can see these macros.
#define SABO_C_CPP 1
#define SABO_JAVA 0
typedef struct {
int time_used;
int memory_used;
int judge_flag;
} sabo_res_t;
item | meaning |
---|---|
time_used |
cost time of your process |
memory_used |
cost memory of your process |
judge_flag |
judge result of you process |
For the meaning of judge_flag
, you can see these macros.
#define SABO_DONE 0
#define SABO_TLE 2
#define SABO_MLE 3
#define SABO_RE 5
#define SABO_RE_DBZ 6
#define SABO_SYSERR 8
#define SABO_MC 10
item | meaning |
---|---|
SABO_DONE |
your process run successfully(Not Accepted !) |
SABO_TLE |
Time Limits Exceed |
SABO_MLE |
Memory Limits Exceed |
SABO_RE |
Runtime Error |
SABO_RE_DBZ |
Runtime Error because the SIGFPE (floating point exception ) |
SABO_SYSERR |
some args invalid and you can get an error string from the interface |
SABO_MC |
you process is malicious(open some important file or calling some invalid syscall) |
const char *sabo_core_run(sabo_ctx_t *ctx, sabo_res_t *info);
An error string will be returned, error is NULL if there is no error.
There is one python3 api in api/python3, you can get the so file if run this command.
python3 setup.py build_ext
these api was wrote by myself, it is so simple that you are not expected to use it directly, but you can reference it.
If you are the guy who like LUA, then luajit will be recommended, you can call C funtions with pure LUA code. See the t/test_libsabocore.lua.
Others also work.
- the syscall list and open file list can be custom in the future.
- if you want
SPECIAL JUDGE
, you can run the code with libsabocore firstly, then run the spjcode directly because the spj code is in mastery.