예제 #1
0
	result_t execute() {
		if (!sandbox_check(&sandbox)) {
			fprintf(stderr, "sandbox pre-execution state check failed\n");
			exit(EX_DATAERR);
		}
		return *sandbox_execute(&sandbox);
	}
예제 #2
0
파일: sandbox.c 프로젝트: LiuCihang/OJ
result_t *
sandbox_execute(sandbox_t * psbox)
{
    FUNC_BEGIN("sandbox_execute(%p)", psbox);

    assert(psbox);

    if (psbox == NULL)
    {
        WARNING("psbox: bad pointer");
        FUNC_RET(NULL, "sandbox_execute()");
    }

    if (!sandbox_check(psbox))
    {
        WARNING("sandbox pre-execution state check failed");
        FUNC_RET(&psbox->result, "sandbox_execute()");
    }

#ifdef WITH_CUSTOM_MONITOR
    pthread_t tid;

    if (pthread_create(&tid, NULL, psbox->ctrl.monitor, (void *)psbox) != 0)
    {
        WARNING("failed creating the monitor thread");
        FUNC_RET(&psbox->result, "sandbox_execute()");
    }
    DBG("created the monitor thread");
#endif /* WITH_CUSTOM_MONITOR */

    /* Fork the prisoner process */
    psbox->ctrl.pid = fork();

    /* Execute the prisoner program */
    if (psbox->ctrl.pid == 0)
    {
        DBG("entering: the prisoner program");
        /* Start executing the prisoner program */
        _exit(__sandbox_task_execute(&psbox->task));
    }
    else
    {
        DBG("target program forked as pid %d", psbox->ctrl.pid);
        /* Start executing the tracing thread */
        psbox->ctrl.tracer(psbox);
    }

#ifdef WITH_CUSTOM_MONITOR
    if (pthread_join(tid, NULL) != 0)
    {
        WARNING("failed joining the monitor thread");
        if (pthread_cancel(tid) != 0)
        {
            WARNING("failed canceling the monitor thread");
            FUNC_RET(NULL, "sandbox_execute()");
        }
    }
    DBG("joined the monitor thread");
#endif /* WITH_CUSTOM_MONITOR */

    FUNC_RET(&psbox->result, "sandbox_execute()");
}