/* Remove FILEs, honoring options specified via X. Return RM_OK if successful. */ enum RM_status rm (char *const *file, struct rm_options const *x) { enum RM_status rm_status = RM_OK; if (*file) { int bit_flags = (FTS_CWDFD | FTS_NOSTAT | FTS_PHYSICAL); if (x->one_file_system) bit_flags |= FTS_XDEV; FTS *fts = xfts_open (file, bit_flags, NULL); while (1) { FTSENT *ent; ent = fts_read (fts); if (ent == NULL) { if (errno != 0) { error (0, errno, _("fts_read failed")); rm_status = RM_ERROR; } break; } enum RM_status s = rm_fts (fts, ent, x); assert (VALID_STATUS (s)); UPDATE_STATUS (rm_status, s); } if (fts_close (fts) != 0) { error (0, errno, _("fts_close failed")); rm_status = RM_ERROR; } } return rm_status; }
void AmeCtrlJobList::OnChar(wxKeyEvent& event){ //POP(SP1("%d", event.GetKeyCode())); if(event.GetKeyCode()<128){ long item = NEXT(-1); if(item>-1){ AmeJob *j = GET(item); AdbFile *f = j->getAdbFile(); if(f){ switch(event.GetKeyCode()){ case 'A': MYEXEC(f->urlAnime()); break; case 'M': MYEXEC(f->urlMylist()); break; case 'N': MYEXEC(f->urlMylistX()); break; case 'E': MYEXEC(f->urlEpisode()); break; case 'G': MYEXEC(f->urlGroup()); break; case 'F': MYEXEC(f->urlFile()); break; case 'K': MYEXEC(f->urlExport()); break; case 'C': AVDUMP(j->getAbsolutePath()); MYEXEC(f->urlFile()); break; } } switch(event.GetKeyCode()){ case 'W': MYEXEC(j->getAbsolutePath()); break; case 'X': MYEXPL(j->getFolderPath()); break; case 'P': {UPDATE_STATUS(jH_PAUSED);} break; case 'S': AmeJobMan::updateStatus(j, jIDENTIFIED); break; case 'I': j->deleteAdbFile(); AmeJobMan::updateStatus(j, jHASHED); break; case ' ': case 13: showInfo(this); break; //case 39: if(m_tt!=null) m_tt.expandRow(); break; //case 37: if(m_tt!=null) m_tt.collapseRow(); break; //default: POP(SP1("%d", event.GetKeyCode())); } } }else event.Skip(); }
/* * Initialize the transaction descriptor before start or restart. */ static inline void stm_prepare(stm_tx_t *tx) { start: /* Start timestamp */ tx->start = tx->end = GET_CLOCK; /* OPT: Could be delayed until first read/write */ /* Allow extensions */ tx->can_extend = 1; if (tx->start >= VERSION_MAX) { /* Block all transactions and reset clock */ stm_quiesce_barrier(tx, rollover_clock, NULL); goto start; } /* Read/write set */ tx->w_set.has_writes = 0; tx->w_set.nb_entries = 0; tx->r_set.nb_entries = 0; /* Set status */ UPDATE_STATUS(tx->status, TX_ACTIVE); stm_check_quiesce(tx); }
// // LoadResources // void Game::LoadResources() { int i; static bool Loaded = false; char filename[MAX_STR_LENGTH], completeFilename[MAX_STR_LENGTH]; if(!Loaded) { UPDATE_STATUS("Loading resources..."); for(i=0; i<MAX_SPRITES; i++) spriteImgs[i] = NULL; for(i=0; i<MAX_TEXTURES; i++) { textures[i][0] = NULL; textures[i][1] = NULL; } UPDATE_STATUS("Loading textures..."); for(i=0; i<MAX_TEXTURES; i++) { sprintf(filename, "textures/map1/tex%d.bmp",i+1); sprintf(completeFilename, "%s%s", DATA_PREFIX, filename); if(framework->FileExists(completeFilename)) { textures[i][0] = framework->LoadImage(filename, false); sprintf(filename, "textures/map1/tex%dDark.bmp", i+1); textures[i][1] = framework->LoadImage(filename, false); } else break; } numTextures = i; UPDATE_STATUS("Loading sprites..."); for(i=0; i<MAX_SPRITES; i++) { sprintf(filename, "sprites/map1/sprite%d.bmp", i+1); sprintf(completeFilename, "%s%s", DATA_PREFIX, filename); if(framework->FileExists(completeFilename)) spriteImgs[i] = framework->LoadImage(filename, true); else break; } } UPDATE_STATUS("Loading ui images..."); if(lowQuality) { hudBgImg = framework->LoadImage("images\\lowQuality\\hudBg.bmp", false); crosshairImg = framework->LoadImage("images\\lowQuality\\crosshair.bmp", true); headImg = framework->LoadImage("images\\lowQuality\\head.bmp", true); headRedImg = framework->LoadImage("images\\lowQuality\\headRed.bmp", true); gunHudImg = framework->LoadImage("images\\lowQuality\\gunHud.bmp", true); gunImg = framework->LoadImage("images\\lowQuality\\gun.bmp", true); fireImg = framework->LoadImage("images\\lowQuality\\fire.bmp", true); keyImg = framework->LoadImage("images\\lowQuality\\key.bmp", true); } else { hudBgImg = framework->LoadImage("images/hudBg.bmp", false); crosshairImg = framework->LoadImage("images/crosshair.bmp", true); headImg = framework->LoadImage("images/head.bmp", true); headRedImg = framework->LoadImage("images/headRed.bmp", true); gunHudImg = framework->LoadImage("images/gunHud.bmp", true); gunImg = framework->LoadImage("images/gun.bmp", true); fireImg = framework->LoadImage("images/fire.bmp", true); keyImg = framework->LoadImage("images/key.bmp", true); MGgunImg = framework->LoadImage("images/mg.bmp", true); MGfireImg = framework->LoadImage("images/mg_fire.bmp", true); MGgunHudImg = framework->LoadImage("images/mg_Hud.bmp", true); SDL_SetAlpha(hudBgImg, SDL_SRCALPHA, SDL_ALPHA_OPAQUE / 2); SDL_SetAlpha(headRedImg, SDL_SRCALPHA, SDL_ALPHA_OPAQUE / 2); } crosshairRect.x = (framework->GetScrW() - crosshairImg->w) / 2; crosshairRect.y = (framework->GetScrH() - crosshairImg->h) / 2; crosshairRect.w = crosshairImg->w; crosshairRect.h = crosshairImg->h; UPDATE_STATUS("Loading Music resources..."); if(!framework->GetNoSound()) { if(!Loaded) { music1 = framework->LoadMusic("music/music1.ogg"); Loaded = true; } UPDATE_STATUS("Loading Sounds resources..."); startSnd = framework->LoadSound("sounds/startround.ogg"); shootSnd = framework->LoadSound("sounds/shot.ogg"); killSnd = framework->LoadSound("sounds/scream.ogg"); pickAmmoSnd = framework->LoadSound("sounds/pickammo.ogg"); PlayerHurt = framework->LoadSound("sounds/PlayerHurt.ogg"); EnemyHurt = framework->LoadSound("sounds/EnemyHurt.ogg"); PlayerDead = framework->LoadSound("sounds/PlayerDead.ogg"); pickKey = framework->LoadSound("sounds/pickKey.ogg"); pickHealth = framework->LoadSound("sounds/pickHealth.ogg"); LVLClear = framework->LoadSound("sounds/LVLClear.ogg"); MGshootSnd = framework->LoadSound("sounds/MGshoot.ogg"); HeartBeat = framework->LoadSound("sounds/HeartBeat.ogg"); UPDATE_STATUS("Loading Extra Sounds resources..."); framework->GlobalSounds(); } }
sigjmp_buf * hytm_start(TXPARAMS stm_tx_attr_t attr) { TX_GET; unsigned long err; tx->retries = 0; /* Set status */ UPDATE_STATUS(tx->status, TX_ACTIVE); stm_check_quiesce(tx); /* copy attributes if need to switch to software mode */ tx->attr = attr; tx->start = rdtsc(); hytm_restart: /* All registers are lost when ASF aborts, thus we discard registers */ asm volatile (ASF_SPECULATE :"=a" (err) : :"memory","rbp","rbx","rcx","rdx","rsi","rdi", "r8", "r9","r10","r11","r12","r13","r14","r15" ); tx = tls_get_tx(); if (unlikely(asf_status_code(err) != 0)) { /* Set status to ABORTED */ SET_STATUS(tx->status, TX_ABORTED); tx->retries++; /* Error management */ if (asf_status_code(err) == ASF_STATUS_CONTENTION) { if (tx->retries > ASF_ABORT_THRESHOLD) { /* There is too many conflicts, software will not help, start irrevocability. */ stm_set_irrevocable(TXARGS 1); /* Set irrevocable serial */ #if defined(TM_DTMC) || defined(TM_GCC) stm_set_irrevocable(TXARGS -1); /* Acquire irrevocability */ UPDATE_STATUS(tx->status, TX_IRREVOCABLE); LONGJMP(tx->env, 0x02); /* ABI 0x02 = runUninstrumented */ #else /* ! defined(TM_DTMC) && ! defined(TM_GCC) */ /* Non-tm compiler doesn't have path without instrumentation. */ tx->software = 1; #endif /* ! defined(TM_DTMC) && ! defined(TM_GCC) */ } } else if (asf_status_code(err) == ASF_STATUS_ABORT) { if (asf_abort_code(err) == ASF_FORCE_SOFTWARE) { tx->software = 1; #ifdef IRREVOCABLE_ENABLED } else if(asf_abort_code(err) == ASF_RETRY_IRREVOCABLE) { # if defined(TM_DTMC) || defined(TM_GCC) if (tx->irrevocable != 0) { stm_set_irrevocable(TXARGS -1); UPDATE_STATUS(tx->status, TX_IRREVOCABLE); LONGJMP(tx->env, 0x02); /* ABI 0x02 = runUninstrumented */ } # else /* ! defined(TM_DTMC) || defined(TM_GCC) */ /* Non-tm compiler doesn't have path without instrumentation. */ tx->software = 1; # endif /* ! defined(TM_DTMC) || defined(TM_GCC) */ #endif /* IRREVOCABLE_ENABLED */ } else { if (tx->retries > ASF_ABORT_THRESHOLD) { tx->software = 1; } } } else { /* Other cases are critical and needs software mode */ tx->software = 1; } if (tx->software) { /* Start a software transaction (it cannot use attr since the register/stack can be corrupted) */ stm_start(TXARGS tx->attr); /* Restoring the context */ #if defined(TM_DTMC) LONGJMP(tx->env, 0x01); /* ABI 0x01 = runInstrumented, DTMC explicitly needs 1 */ #else /* ! defined(TM_DTMC) */ LONGJMP(tx->env, 0x09); /* ABI 0x09 = runInstrumented + restoreLiveVariable */ #endif /* ! defined(TM_DTMC) */ } else { uint64_t cur = (uint64_t)rdtsc(); uint64_t wait = cur + (random() % (cur - tx->start)); /* XXX random but maybe not reliable */ /* Waiting... */ while (rdtsc() < wait); UPDATE_STATUS(tx->status, TX_ACTIVE); /* Check quiesce before to restart */ stm_check_quiesce(tx); goto hytm_restart; } } /* Reset write set */ tx->w_set.nb_entries = 0; if (tx->retries > 0) { /* Restoring registers for retry */ #if defined(TM_DTMC) LONGJMP(tx->env, 0x01); /* ABI 0x01 = runInstrumented, DTMC explicitly needs 1 */ #else /* ! defined(TM_DTMC) */ LONGJMP(tx->env, 0x09); /* ABI 0x09 = runInstrumented + restoreLiveVariable */ #endif /* ! defined(TM_DTMC) */ } return &tx->env; }
void AmeCtrlJobList::DoApplyRules(wxCommandEvent& WXUNUSED(event)){ UPDATE_STATUS(jIDENTIFIED); }
void AmeCtrlJobList::DoPause(wxCommandEvent& WXUNUSED(event)){ UPDATE_STATUS(jH_PAUSED); }
UPDATE_STATUS(jIDENTIFIED); } void AmeCtrlJobList::DoWatchNow(wxCommandEvent& WXUNUSED(event)){ AmeJob *j = GetSelectedJob(); if(j&&!j->check(jH_MISSING)){ MYEXEC(j->getAbsolutePath()); } } void AmeCtrlJobList::DoExploreFolder(wxCommandEvent& WXUNUSED(event)){ AmeJob *j = GetSelectedJob(); if(j&&!j->check(jH_MISSING)){ MYEXPL(j->getFolderPath()); } } void AmeCtrlJobList::DoReHash(wxCommandEvent& WXUNUSED(event)){ UPDATE_STATUS(jHASHWAIT) } void AmeCtrlJobList::DoReId(wxCommandEvent& WXUNUSED(event)){ UPDATE_STATUS(jHASHED) } void AmeCtrlJobList::DoReAdd(wxCommandEvent& WXUNUSED(event)){ UPDATE_STATUS(jADDWAIT) } void AmeCtrlJobList::DoRemove(wxCommandEvent& WXUNUSED(event)){ UPDATE_STATUS(jREMWAIT) } void AmeCtrlJobList::DoSetFinished(wxCommandEvent& WXUNUSED(event)){ UPDATE_STATUS(jFINISHED) } void AmeCtrlJobList::DoRestoreName(wxCommandEvent& WXUNUSED(event)){ REFRESH_BLOCK(AmeJobMan::restoreName(j));
static void * __sandbox_tracer(sandbox_t * psbox) { FUNC_BEGIN("sandbox_tracer(%p)", psbox); assert(psbox); #define UPDATE_RESULT(psbox,res) \ {{{ \ if (((psbox)->result) != (result_t)(res)) \ { \ ((psbox)->result) = (result_t)(res); \ } \ DBG("result: %s", s_result_name((result_t)(res))); \ }}} /* UPDATE_RESULT */ #define UPDATE_STATUS(psbox,sta) \ {{{ \ P(&((psbox)->mutex)); \ if (((psbox)->status) != (status_t)(sta)) \ { \ ((psbox)->status) = (status_t)(sta); \ pthread_cond_broadcast(&((psbox)->update)); \ } \ V(&((psbox)->mutex)); \ DBG("status: %s", s_status_name((status_t)(sta))); \ }}} /* UPDATE_STATUS */ #define SIGMLE SIGUSR1 #define TIMEVAL_INPLACE_SUBTRACT(x,y) \ {{{ \ if ((x).tv_usec < (y).tv_usec) \ { \ int nsec = ((y).tv_usec - (x).tv_usec) / 1000000 + 1; \ (x).tv_sec -= nsec; \ (x).tv_usec += 1000000 * nsec; \ } \ if ((x).tv_usec - (y).tv_usec >= 1000000) \ { \ int nsec = ((y).tv_usec - (x).tv_usec) / 1000000; \ (x).tv_usec -= 1000000 * nsec; \ (x).tv_sec += nsec; \ } \ (x).tv_sec -= (y).tv_sec; \ (x).tv_usec -= (y).tv_usec; \ }}} /* TIMEVAL_INPLACE_SUBTRACT */ #define CLEAR_EVENT(pctrl) \ {{{ \ P(&((pctrl)->mutex)); \ ((pctrl)->idle) = true; \ pthread_cond_broadcast(&((pctrl)->sched)); \ V(&((pctrl)->mutex)); \ }}} /* CLEAR_EVENT */ #define POST_EVENT(pctrl,type,x...) \ {{{ \ P(&((pctrl)->mutex)); \ ((pctrl)->event) = (event_t){(S_EVENT ## type), {{x}}}; \ ((pctrl)->idle) = false; \ pthread_cond_broadcast(&((pctrl)->sched)); \ V(&((pctrl)->mutex)); \ }}} /* POST_EVENT */ #ifdef WITH_CUSTOM_MONITOR #define SINK_EVENT(pctrl) \ {{{ \ P(&((pctrl)->mutex)); \ while (!IS_IDLE(pctrl)) \ { \ pthread_cond_wait(&((pctrl)->sched), &((pctrl)->mutex)); \ } \ V(&((pctrl)->mutex)); \ }}} /* SINK_EVENT */ #endif /* WITH_CUSTOM_MONITOR */ #ifdef WITH_NATIVE_MONITOR #define SINK_EVENT(pctrl) \ {{{ \ P(&((pctrl)->mutex)); \ if (IS_IDLE(pctrl)) \ { \ DBG("no event detected"); \ V(&((pctrl)->mutex)); \ goto cont; \ } \ V(&((pctrl)->mutex)); \ \ DBG("detected event: %s {%lu %lu %lu %lu %lu %lu %lu}", \ s_event_type_name((pctrl)->event.type), \ (pctrl)->event.data.__bitmap__.A, \ (pctrl)->event.data.__bitmap__.B, \ (pctrl)->event.data.__bitmap__.C, \ (pctrl)->event.data.__bitmap__.D, \ (pctrl)->event.data.__bitmap__.E, \ (pctrl)->event.data.__bitmap__.F, \ (pctrl)->event.data.__bitmap__.G); \ \ ((policy_entry_t)(pctrl)->policy.entry)(&(pctrl)->policy, \ &(pctrl)->event, \ &(pctrl)->action); \ \ DBG("decided action: %s {%lu %lu}", \ s_action_type_name((pctrl)->action.type), \ (pctrl)->action.data.__bitmap__.A, \ (pctrl)->action.data.__bitmap__.B); \ \ P(&((pctrl)->mutex)); \ ((pctrl)->idle) = true; \ pthread_cond_broadcast(&((pctrl)->sched)); \ V(&((pctrl)->mutex)); \ }}} /* SINK_EVENT */ #endif /* WITH_NATIVE_MONITOR */ DBG("entering: the tracing thread"); /* The controller should contain pid of the prisoner process */ pid_t pid = psbox->ctrl.pid; /* Check if the prisoner process was correctly forked */ if (pid < 0) { WARNING("error forking the prisoner process"); UPDATE_RESULT(psbox, S_RESULT_IE); UPDATE_STATUS(psbox, S_STATUS_FIN); FUNC_RET((void *)&psbox->result, "sandbox_tracer()"); } /* Have signals kill the prisoner but not self (if possible). */ sighandler_t terminate_signal; sighandler_t interrupt_signal; sighandler_t quit_signal; terminate_signal = signal(SIGTERM, SIG_IGN); interrupt_signal = signal(SIGINT, SIG_IGN); quit_signal = signal(SIGQUIT, SIG_IGN); /* Get wallclock start time */ gettimeofday(&psbox->stat.started, NULL); UPDATE_RESULT(psbox, S_RESULT_PD); UPDATE_STATUS(psbox, S_STATUS_EXE); /* Resume the control logic */ CLEAR_EVENT(&psbox->ctrl); /* Temporary variables. */ struct rusage initru; int waitstatus = 0; pid_t waitresult = 0; proc_t proc = {0}; /* System call stack. The prisoner process initially stops at *SYSRET* mode * after making the first call to SYS_execve. Therefore, we initialize the * stack as it is. */ int sc_stack[16] = {0, SYS_execve}; int sc_top = 1; /* Make an initial wait to verify the first system call as well as to * collect resource usage overhead. */ waitresult = wait4(pid, &waitstatus, 0, &psbox->stat.ru); UPDATE_STATUS(psbox, S_STATUS_BLK); /* Save the initial resource usage for further reference */ memcpy(&initru, &psbox->stat.ru, sizeof(struct rusage)); /* Clear cache in order to increase timing accuracy */ flush_cache(); flush_cache(); /* Entering the tracing loop */ do { /* Trace state refresh of the prisoner program */ UPDATE_STATUS(psbox, S_STATUS_BLK); /* In case nothing happened (possible when the 3rd argument of *wait4* * contains the WNOHANG flag), we just go on with next wait(). */ if (waitresult == 0) { DBG("wait: nothing happened"); goto cont; } /* Figure *net* resource usage (eliminate initru) */ TIMEVAL_INPLACE_SUBTRACT(psbox->stat.ru.ru_utime, initru.ru_utime); TIMEVAL_INPLACE_SUBTRACT(psbox->stat.ru.ru_stime, initru.ru_stime); psbox->stat.ru.ru_majflt -= initru.ru_majflt; psbox->stat.ru.ru_minflt -= initru.ru_minflt; psbox->stat.ru.ru_nswap -= initru.ru_nswap; DBG("ru.ru_utime.tv_sec % 10ld", psbox->stat.ru.ru_utime.tv_sec); DBG("ru.ru_utime.tv_usec % 10ld", psbox->stat.ru.ru_utime.tv_usec); DBG("ru.ru_stime.tv_sec % 10ld", psbox->stat.ru.ru_stime.tv_sec); DBG("ru.ru_stime.tv_usec % 10ld", psbox->stat.ru.ru_stime.tv_usec); DBG("ru.ru_majflt % 10ld", psbox->stat.ru.ru_majflt); DBG("ru.ru_minflt % 10ld", psbox->stat.ru.ru_minflt); DBG("ru.ru_nswap % 10ld", psbox->stat.ru.ru_nswap); /* Raise appropriate events judging each wait status */ if (WIFSTOPPED(waitstatus)) { DBG("wait: stopped (%d)", WSTOPSIG(waitstatus)); psbox->stat.signal = WSTOPSIG(waitstatus); /* Collect additional information of the prisoner process */ if (!proc_probe(pid, PROBE_STAT, &proc)) { WARNING("failed to probe the prisoner process"); kill(-pid, SIGKILL); UPDATE_RESULT(psbox, S_RESULT_IE); goto done; } /* Raise appropriate event judging stop signal */ switch (WSTOPSIG(waitstatus)) { case SIGALRM: /* real timer expired */ POST_EVENT(&psbox->ctrl, _QUOTA, S_QUOTA_WALLCLOCK); break; case SIGXCPU: /* CPU resource limit exceed */ case SIGPROF: /* profile timer expired */ case SIGVTALRM: /* virtual timer expired */ POST_EVENT(&psbox->ctrl, _QUOTA, S_QUOTA_CPU); break; case SIGMLE: /* SIGUSR1 used for reporting ML */ POST_EVENT(&psbox->ctrl, _QUOTA, S_QUOTA_MEMORY); break; case SIGXFSZ: /* Output file size exceeded */ POST_EVENT(&psbox->ctrl, _QUOTA, S_QUOTA_DISK); break; case SIGTRAP: /* Update the tsc instructions counter */ #ifdef WITH_TSC_COUNTER psbox->stat.tsc++; DBG("tsc %010llu", psbox->stat.tsc); #endif /* WITH_TSC_COUNTER */ /* Collect additional information of prisoner process */ if (!proc_probe(pid, PROBE_REGS, &proc)) { WARNING("failed to probe the prisoner process"); kill(-pid, SIGKILL); UPDATE_RESULT(psbox, S_RESULT_IE); goto done; } /* Update sandbox stat with the process runtime info */ { psbox->stat.vsize = proc.vsize; if (psbox->stat.vsize_peak < proc.vsize) { psbox->stat.vsize_peak = proc.vsize; } psbox->stat.rss = proc.rss * getpagesize(); } /* Detect memory usage against quota */ if (psbox->stat.vsize_peak > psbox->task.quota[S_QUOTA_MEMORY]) { kill(-pid, SIGMLE); } /* For `single step' tracing mode, we have to probe the current * op code (i.e. INT80 for i386 platforms) to tell whether the * prisoner process is invoking a system call. For `system call' * tracing mode, however, every *SIGTRAP* indicates a system * call currently being invoked or just returned. */ #ifdef WITH_TSC_COUNTER if (IS_SYSCALL(&proc) || IS_SYSRET(&proc)) #endif /* WITH_TSC_COUNTER */ { int scno = THE_SYSCALL(&proc); if (scno != sc_stack[sc_top]) { sc_stack[++sc_top] = scno; psbox->stat.syscall = scno; SET_IN_SYSCALL(&proc); POST_EVENT(&psbox->ctrl, _SYSCALL, scno, SYSCALL_ARG1(&proc), SYSCALL_ARG2(&proc), SYSCALL_ARG3(&proc), SYSCALL_ARG4(&proc), SYSCALL_ARG5(&proc)); } else { CLR_IN_SYSCALL(&proc); sc_stack[sc_top--] = 0; POST_EVENT(&psbox->ctrl, _SYSRET, scno, SYSRET_RETVAL(&proc)); } } #ifdef WITH_TSC_COUNTER else { goto next; } #endif /* WITH_TSC_COUNTER */ break; default: /* Other runtime error */ POST_EVENT(&psbox->ctrl, _SIGNAL, WSTOPSIG(waitstatus)); break; } } /* stopped */ else if (WIFSIGNALED(waitstatus)) { DBG("wait: signaled (%d)", WTERMSIG(waitstatus)); psbox->stat.signal = WTERMSIG(waitstatus); POST_EVENT(&psbox->ctrl, _SIGNAL, WTERMSIG(waitstatus)); } else if (WIFEXITED(waitstatus)) { DBG("wait: exited (%d)", WEXITSTATUS(waitstatus)); psbox->stat.exitcode = WEXITSTATUS(waitstatus); POST_EVENT(&psbox->ctrl, _EXIT, WEXITSTATUS(waitstatus)); } /* Wait for the policy to determine the next action */ SINK_EVENT(&psbox->ctrl); /* Perform the desired action */ switch (psbox->ctrl.action.type) { case S_ACTION_CONT: next: #ifdef WITH_TSC_COUNTER if (!trace_next(&proc, TRACE_SINGLE_STEP)) #else if (!trace_next(&proc, TRACE_SYSTEM_CALL)) #endif /* WITH_TSC_COUNTER */ { WARNING("trace_next"); kill(-pid, SIGKILL); UPDATE_RESULT(psbox, S_RESULT_IE); break; } /* There is no need to update state here! */ goto cont; /* Continue with next wait() */ case S_ACTION_FINI: UPDATE_RESULT(psbox, psbox->ctrl.action.data._FINI.result); break; case S_ACTION_KILL: /* Using trace_kill can effectively prevent overrun of undesired * behavior, i.e. illegal system call. */ trace_kill(&proc, SIGKILL); UPDATE_RESULT(psbox, psbox->ctrl.action.data._KILL.result); break; } break; /* Exiting the tracing loop! */ cont: /* Wait until the prisoner process is trapped */ UPDATE_STATUS(psbox, S_STATUS_EXE); DBG("----------------------------------------------------------------"); DBG("wait4(%d,%p,%d,%p)", pid, &waitstatus, 0, &psbox->stat.ru); waitresult = waitstatus = 0; } while ((waitresult = wait4(pid, &waitstatus, 0, &psbox->stat.ru)) >= 0); done: /* Get wallclock stop time (call a second time to compensate overhead) */ gettimeofday(&psbox->stat.stopped, NULL); UPDATE_STATUS(psbox, S_STATUS_FIN); /* Resume the control logic */ CLEAR_EVENT(&psbox->ctrl); DBG("leaving: the tracing thread"); /* Restore signal handlers */ signal(SIGTERM, interrupt_signal); signal(SIGINT, interrupt_signal); signal(SIGQUIT, quit_signal); FUNC_RET((void *)&psbox->result, "sandbox_tracer()"); }