result_t execute() { if (!sandbox_check(&sandbox)) { fprintf(stderr, "sandbox pre-execution state check failed\n"); exit(EX_DATAERR); } return *sandbox_execute(&sandbox); }
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()"); }