void setup_sage_signal_handler() { /* Reset the _signals structure */ memset(&_signals, 0, sizeof(_signals)); /* Save the default signal mask */ sigprocmask(SIG_BLOCK, NULL, &default_sigmask); /* Save the signal mask with non-critical signals blocked */ sigprocmask(SIG_BLOCK, NULL, &sigmask_with_sigint); sigaddset(&sigmask_with_sigint, SIGHUP); sigaddset(&sigmask_with_sigint, SIGINT); sigaddset(&sigmask_with_sigint, SIGALRM); /* Install signal handlers */ struct sigaction sa; memset(&sa, 0, sizeof(sa)); /* Block non-critical signals during the signal handlers */ sigemptyset(&sa.sa_mask); sigaddset(&sa.sa_mask, SIGHUP); sigaddset(&sa.sa_mask, SIGINT); sigaddset(&sa.sa_mask, SIGALRM); sa.sa_handler = sage_interrupt_handler; if (sigaction(SIGHUP, &sa, NULL)) {perror("sigaction"); exit(1);} if (sigaction(SIGINT, &sa, NULL)) {perror("sigaction"); exit(1);} sa.sa_handler = sage_signal_handler; /* Allow signals during signal handling, we have code to deal with * this case. */ sa.sa_flags |= SA_NODEFER; if (sigaction(SIGILL, &sa, NULL)) {perror("sigaction"); exit(1);} if (sigaction(SIGABRT, &sa, NULL)) {perror("sigaction"); exit(1);} if (sigaction(SIGFPE, &sa, NULL)) {perror("sigaction"); exit(1);} if (sigaction(SIGBUS, &sa, NULL)) {perror("sigaction"); exit(1);} if (sigaction(SIGSEGV, &sa, NULL)) {perror("sigaction"); exit(1);} /* If the CPU architecture is x86, check whether the EMMS * instruction is supported by executing it and catching a * possible SIGILL (illegal instruction signal). */ #ifdef CPU_ARCH_x86 if (!cpu_has_emms) { if (sig_on_no_except()) /* try: */ { asm("emms"); sig_off(); cpu_has_emms = 1; } else /* except: */ { PyErr_Clear(); /* Clear Python exception */ } } #endif }
void QueryCvarProvider::InitCookie() { if (m_engine_cvar_cookie) return; DebugMessage("Trying to get g_iQueryCvarCookie ..."); basic_string modulename("engine"); #ifdef GNUC if (SourceSdk::InterfacesProxy::m_game != SourceSdk::CounterStrikeGlobalOffensive) { modulename.append("_srv"); } #endif #ifdef WIN32 modulename.append(".dll"); HMODULE engine_module_handle(GetModuleHandleA(modulename.c_str())); mem_byte * pstart(nullptr); mem_byte * pend(nullptr); if (engine_module_handle != NULL) { MODULEINFO modinfo; K32GetModuleInformation(GetCurrentProcess(), engine_module_handle, &modinfo, sizeof(MODULEINFO)); pstart = (mem_byte*)modinfo.lpBaseOfDll; pend = pstart + 0x44A400; mem_byte *sig_code(nullptr); mem_byte * sig_mask(nullptr); size_t sig_size(0); size_t sig_off(0); if (SourceSdk::InterfacesProxy::m_game == SourceSdk::CounterStrikeGlobalOffensive) { sig_code = new mem_byte[156] { 0x55, 0x8B, 0xEC, 0x83, 0xE4, 0xF8, 0x83, 0xEC, 0x3C, 0x56, 0x8B, 0x75, 0x08, 0x2B, 0x35, 0xD4, 0x12, 0x7B, 0x10, 0xC1, 0xFE, 0x04, 0x83, 0xFE, 0x01, 0x7C, 0x08, 0x3B, 0x35, 0x98, 0x11, 0x7B, 0x10, 0x7E, 0x0D, 0x68, 0xB0, 0x39, 0x4A, 0x10, 0xE8, 0x63, 0x0B, 0x06, 0x00, 0x83, 0xC4, 0x04, 0xA1, 0x8C, 0x11, 0x7B, 0x10, 0x8D, 0x4C, 0x24, 0x08, 0x8B, 0x74, 0xB0, 0xFC, 0x8D, 0x46, 0x04, 0xF7, 0xDE, 0x1B, 0xF6, 0x23, 0xF0, 0xE8, 0x15, 0x4F, 0xEF, 0xFF, 0xA1, 0x38, 0xCE, 0x52, 0x10, 0x8B, 0xC8, 0xFF, 0x75, 0x0C, 0x83, 0x4C, 0x24, 0x24, 0x01, 0x40, 0x89, 0x4C, 0x24, 0x1C, 0x8D, 0x4C, 0x24, 0x10, 0xA3, 0x38, 0xCE, 0x52, 0x10, 0xE8, 0x53, 0x5F, 0xFF, 0xFF, 0x8B, 0x06, 0x8D, 0x4C, 0x24, 0x08, 0x83, 0x4C, 0x24, 0x20, 0x01, 0xF7, 0x5C, 0x24, 0x18, 0x6A, 0x00, 0x6A, 0x00, 0x51, 0x8B, 0xCE, 0xFF, 0x50, 0x7C, 0x8B, 0x74, 0x24, 0x18, 0x8D, 0x4C, 0x24, 0x08, 0xE8, 0x5D, 0x18, 0xEF, 0xFF, 0x8B, 0xC6, 0x5E, 0x8B, 0xE5, 0x5D, 0xC2, 0x08, 0x00 }; sig_mask = new mem_byte[156] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; sig_off = 0x4C; sig_size = 156; } else { sig_code = new mem_byte[105] { 0x55, 0x8B, 0xEC, 0x81, 0xEC, 0x18, 0x01, 0x00, 0x00, 0xA1, 0x7C, 0x2A, //T 0x3C, 0x10, 0x8B, 0xC8, 0x40, 0xC6, 0x85, 0xEC, 0xFE, 0xFF, 0xFF, 0x01, 0x80, 0x7D, 0x10, 0x00, 0xA3, 0x7C, 0x2A, 0x3C, //T 0x10, 0x8B, 0x45, 0x0C, 0xC7, 0x85, 0xF0, 0xFE, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x85, 0xE8, 0xFE, 0xFF, 0xFF, 0x60, 0x51, 0x2F, 0x10, 0x89, 0x8D, 0xF8, 0xFE, 0xFF, 0xFF, 0x89, 0x85, 0xFC, 0xFE, 0xFF, 0xFF, 0x75, 0x08, 0xF7, 0xD9, 0x89, 0x8D, 0xF8, 0xFE, 0xFF, 0xFF, 0x8B, 0x4D, 0x08, 0x8D, 0x95, 0xE8, 0xFE, 0xFF, 0xFF, 0x6A, 0x00, 0x52, 0x8B, 0x01, 0xFF, 0x50, 0x74, 0x8B, 0x85, 0xF8, 0xFE, 0xFF, 0xFF, 0x8B, 0xE5, 0x5D, 0xC3 }; sig_mask = new mem_byte[105] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, //T 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, //T 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; sig_off = 0xA; sig_size = 105; } sig_ctx ctx(sig_code, sig_mask, sig_size, sig_off); #else modulename.append(".so"); basic_string relpath(Helpers::format("./bin/%s", modulename.c_str())); void ** modinfo = (void **)dlopen(relpath.c_str(), RTLD_NOW | RTLD_NOLOAD); void * engine_module_handle = nullptr; if (modinfo != NULL) { //mm_module_handle = dlsym(modinfo, ".init_proc"); // FIXME : Use link_map to get memory bounds of the module engine_module_handle = *modinfo; dlclose(modinfo); } if (engine_module_handle) { mem_byte * pstart = (mem_byte*)engine_module_handle; mem_byte * pend = pstart + 0x44A400; mem_byte *sig_code(nullptr); mem_byte * sig_mask(nullptr); size_t sig_size(0); size_t sig_off(0); if (SourceSdk::InterfacesProxy::m_game == SourceSdk::CounterStrikeGlobalOffensive) { sig_code = new mem_byte[234] { 0x55, 0x89, 0xE5, 0x57, 0x56, 0x8D, 0x75, 0xC4, 0x53, 0x83, 0xEC, 0x5C, 0xC7, 0x45, 0xC0, 0x68, 0x8A, 0x54, 0x00, 0x0F, 0xB6, 0x45, 0x10, 0x89, 0x34, 0x24, 0x8B, 0x7D, 0x0C, 0x88, 0x45, 0xB7, 0xE8, 0x0B, 0x4B, 0xF6, 0xFF, 0x8B, 0x15, 0x38, //T 0xD5, 0x72, 0x00, 0xC6, //T 0x45, 0xDC, 0x01, 0x8B, 0x5D, 0xCC, 0xC7, 0x45, 0xC0, 0x88, 0x91, 0x54, 0x00, 0xC7, 0x45, 0xC4, 0xCC, 0x91, 0x54, 0x00, 0xC7, 0x45, 0xE0, 0x9C, 0x4C, 0x7E, 0x00, 0x8D, 0x42, 0x01, 0x89, 0x55, 0xD0, 0xA3, 0x38, 0xD5, 0x72, 0x00, 0x8B, 0x45, 0xD8, 0x83, 0xC8, 0x03, 0x81, 0xFB, 0x00, 0x47, 0x7E, 0x00, 0x89, 0x45, 0xD8, 0x0F, 0x84, 0x89, 0x00, 0x00, 0x00, 0x89, 0x3C, 0x24, 0xE8, 0x75, 0xC9, 0x62, 0x00, 0x89, 0x1C, 0x24, 0x8D, 0x5D, 0xC0, 0x89, 0x44, 0x24, 0x08, 0x89, 0x7C, 0x24, 0x04, 0xE8, 0x42, 0x39, 0x36, 0x00, 0x80, 0x7D, 0xB7, 0x00, 0x75, 0x0C, 0x8B, 0x45, 0xD0, 0x83, 0x4D, 0xD8, 0x01, 0xF7, 0xD8, 0x89, 0x45, 0xD0, 0x8B, 0x55, 0x08, 0x8D, 0x5D, 0xC0, 0x8B, 0x02, 0xC7, 0x44, 0x24, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x44, 0x24, 0x08, 0x00, 0x00, 0x00, 0x00, 0x89, 0x5C, 0x24, 0x04, 0x89, 0x14, 0x24, 0xFF, 0x90, 0x80, 0x00, 0x00, 0x00, 0x8B, 0x55, 0xE0, 0xC7, 0x45, 0xC0, 0x88, 0x91, 0x54, 0x00, 0x8B, 0x5D, 0xD0, 0xC7, 0x45, 0xC4, 0xCC, 0x91, 0x54, 0x00, 0x8D, 0x4A, 0xF4, 0x81, 0xF9, 0x90, 0x4C, 0x7E, 0x00, 0x75, 0x37, 0x89, 0x34, 0x24, 0xE8, 0x40, 0x4B, 0xF6, 0xFF, 0x83, 0xC4, 0x5C, 0x89, 0xD8, 0x5B, 0x5E, 0x5F, 0x5D, 0xC3 }; sig_mask = new mem_byte[234] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, //T 0x00, 0x00, 0x00, 0xFF, //T 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; sig_off = 39; sig_size = 234; } else { sig_code = new mem_byte[116] { 0x55, 0x89, 0xE5, 0x81, 0xEC, 0x38, 0x01, 0x00, 0x00, 0xA1, 0x70, 0xBF, //T 0x2C, 0x00, 0xC6, 0x85, 0xDC, 0xFE, 0xFF, 0xFF, 0x01, 0xC7, 0x85, 0xE0, 0xFE, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x80, 0x7D, 0x10, 0x00, 0xC7, 0x85, 0xD8, 0xFE, 0xFF, 0xFF, 0x68, 0x2E, 0x23, 0x00, 0x8B, 0x55, 0x08, 0x8D, 0x48, 0x01, 0x89, 0x85, 0xE8, 0xFE, 0xFF, 0xFF, 0x89, 0x0D, 0x70, //T 0xBF, 0x2C, 0x00, 0x8B, 0x4D, 0x0C, 0x89, 0x8D, 0xEC, 0xFE, 0xFF, 0xFF, 0x75, 0x08, 0xF7, 0xD8, 0x89, 0x85, 0xE8, 0xFE, 0xFF, 0xFF, 0x8B, 0x02, 0x8D, 0x8D, 0xD8, 0xFE, 0xFF, 0xFF, 0xC7, 0x44, 0x24, 0x08, 0x00, 0x00, 0x00, 0x00, 0x89, 0x4C, 0x24, 0x04, 0x89, 0x14, 0x24, 0xFF, 0x50, 0x78, 0x8B, 0x85, 0xE8, 0xFE, 0xFF, 0xFF, 0xC9, 0xC3 }; sig_mask = new mem_byte[116] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, //T 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, //T 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }; sig_off = 0xA; sig_size = 116; } sig_ctx ctx(sig_code, sig_mask, sig_size, sig_off); #endif ScanMemoryRegion(pstart, pend, &ctx); if (ctx.m_out != nullptr) { m_engine_cvar_cookie = reinterpret_cast<SourceSdk::QueryCvarCookie_t *>(*(reinterpret_cast<size_t**>(ctx.m_out))); if (m_engine_cvar_cookie != nullptr) { DebugMessage(Helpers::format("g_iQueryCvarCookie = %d", *m_engine_cvar_cookie)); } else { g_Logger.Msg<MSG_ERROR>("Failed to get g_iQueryCvarCookie."); } } else { g_Logger.Msg<MSG_ERROR>("Sigscan failed for g_iQueryCvarCookie."); } if (sig_mask) delete[] sig_mask; if (sig_code) delete[] sig_code; } else { DebugMessage("engine module not found."); } } void QueryCvarProvider::FixQueryCvarCookie() { if (m_engine_cvar_cookie) { if (*m_engine_cvar_cookie < 1 || *m_engine_cvar_cookie == std::numeric_limits<SourceSdk::QueryCvarCookie_t>::max()) { *m_engine_cvar_cookie = 1; } } } SourceSdk::QueryCvarCookie_t QueryCvarProvider::StartQueryCvarValue(SourceSdk::edict_t * pEntity, const char * pName) { FixQueryCvarCookie(); return SourceSdk::InterfacesProxy::GetServerPluginHelpers()->StartQueryCvarValue(pEntity, pName); }
int main(int argc, char **argv) { time_t now; /* Initialise route, runq and job classes */ now = time(NULL); route_init(NULL, 0); route_register(&rt_filea_method); route_register(&rt_fileov_method); route_register(&rt_stdin_method); route_register(&rt_stdout_method); route_register(&rt_stderr_method); if ( ! elog_init(1, "job test", NULL)) elog_die(FATAL, "didn't initialise elog\n"); sig_init(); callback_init(); runq_init(now); meth_init(); job_init(); /* Test should fail due to incorrect method */ elog_printf(DEBUG, "Expect a complaint! -> "); if (job_add(5, 5, 0, 1, "test1a1", "internal_test", "stdout", "stderr", 100, NULL, "echo \"Hello, world\"") != -1) { elog_die(FATAL, "[1a] Shouldn't be able to add\n"); } /* Single test in five seconds, never to run */ if (job_add(5, 5, 0, 1, "test1a2", "internal_test", "stdout", "stderr", 100, "exec", "echo \"Hello, world\"") == -1) { elog_die(FATAL, "[1a] Can't add\n"); } /* Attention: some white box testing */ itree_first(runq_event); if (itree_getkey(runq_event) != now+5) { elog_die(FATAL, "[1a] Queued at an incorrect time\n"); } job_clear(); if (!itree_empty(runq_event) || !itree_empty(runq_tab)) { elog_die(FATAL, "[1a] Trees not emptied. runq_events=%d, runq_tab=%d\n", itree_n(runq_event), itree_n(runq_tab)); } now = time(NULL); /* Two tests both in five seconds, never to run */ if (job_add(5, 5, 0, 1, "test1b1", "internal_test", "stdout", "stderr", 100, "exec", "echo \"Hello, world\"") == -1) { elog_die(FATAL, "[1b] Can't add first\n"); } if (job_add(5, 5, 0, 1, "test1b2", "internal_test", "stdout", "stderr", 100, "exec", "echo \"Hello, world\"") == -1) { elog_die(FATAL, "[1b] Can't add second\n"); } itree_first(runq_event); if (itree_getkey(runq_event) != now+5) { elog_die(FATAL, "[1b] First queued at an incorrect time\n"); } itree_next(runq_event); if (itree_getkey(runq_event) != now+5) { elog_die(FATAL, "[1b] Second queued at an incorrect time\n"); } job_clear(); if (!itree_empty(runq_event) || !itree_empty(runq_tab)) { elog_die(FATAL, "[1b] Trees not emptied. runq_events=%d, runq_tab=%d\n", itree_n(runq_event), itree_n(runq_tab)); } now = time(NULL); /* Two tests one in five seconds, the other in six, never to run */ if (job_add(6, 6, 0, 1, "test1c1", "internal_test", "stdout", "stderr", 100, "exec", "echo \"Hello, world\"") == -1) { elog_die(FATAL, "[1c] Can't add first\n"); } if (job_add(now+5, 5, 0, 1, "test1c2", "internal_test", "stdout", "stderr", 100, "exec", "echo \"Hello, world\"") == -1) { elog_die(FATAL, "[1c] Can't add second\n"); } itree_first(runq_event); if (itree_getkey(runq_event) != now+5) { elog_die(FATAL, "[1c] First queued at an incorrect time\n"); } itree_next(runq_event); if (itree_getkey(runq_event) != now+6) { elog_die(FATAL, "[1c] Second queued at an incorrect time\n"); } job_clear(); if (!itree_empty(runq_event) || !itree_empty(runq_tab)) { elog_die(FATAL, "[1c] Trees not emptied. runq_events=%d, runq_tab=%d\n", itree_n(runq_event), itree_n(runq_tab)); } now = time(NULL); /* Continuous single test supposed to start two seconds ago, * next run in three; never to run */ if (job_add(-2, 5, 0, 0, "test1d1", "internal_test", "stdout", "stderr", 100, "exec", "echo \"Hello, world\"") == -1) { elog_die(FATAL, "[1d] Can't add\n"); } itree_first(runq_event); if (itree_getkey(runq_event) != now+3) { elog_die(FATAL, "[1d] Event queued at an incorrect time: bad=%d good=%ld\n", itree_getkey(runq_event), now+3); } job_clear(); if (runq_nsched() > 0) { elog_die(FATAL, "[1d] Still active work scheduled. runq_events=%d, " "runq_tab=%d runq_nsched()=%d\n", itree_n(runq_event), itree_n(runq_tab), runq_nsched()); runq_dump(); } now = time(NULL); /* Two continous tests, starting two seconds ago, next next run in four; * never to run */ if (job_add(-2, 6, 0, 0, "test1e1", "internal_test", "stdout", "stderr", 100, "exec", "echo \"Hello, world\"") == -1) { elog_die(FATAL, "[1e] Can't add first\n"); } if (job_add(-3, 5, 0, 0, "test1e2", "internal_test", "stdout", "stderr", 100, "exec", "echo \"Hello, world\"") == -1) { elog_die(FATAL, "[1e] Can't add second\n"); } itree_first(runq_event); while (((struct runq_work*) itree_get(runq_event))->expired) itree_next(runq_event); if (itree_getkey(runq_event) != now+2) { elog_die(FATAL, "[1e] First queued at an incorrect time\n"); } itree_next(runq_event); while (((struct runq_work*) itree_get(runq_event))->expired) itree_next(runq_event); if (itree_getkey(runq_event) != now+4) { elog_die(FATAL, "[1e] Second queued at an incorrect time\n"); } job_clear(); if (runq_nsched() > 0) { elog_die(FATAL, "[1e] Still active work scheduled. runq_events=%d, " "runq_tab=%d runq_nsched()=%d\n", itree_n(runq_event), itree_n(runq_tab), runq_nsched()); runq_dump(); } now = time(NULL); /* Two 5 run jobs, scheduled to start 10 seconds ago, with periods * of 5 and 6 seconds; never to run */ if (job_add(-10, 6, 0, 5, "test1f1", "internal_test", "stdout", "stderr", 100, "exec", "echo \"Hello, world\"") == -1) { elog_die(FATAL, "[1f] Can't add first\n"); } if (job_add(-10, 5, 0, 5, "test1f2", "internal_test", "stdout", "stderr", 100, "exec", "echo \"Hello, world\"") == -1) { elog_die(FATAL, "[1f] Can't add second\n"); } itree_first(runq_event); while (((struct runq_work*) itree_get(runq_event))->expired) itree_next(runq_event); if (itree_getkey(runq_event) != now+2) { elog_die(FATAL, "[1f] First queued at an incorrect time\n"); } itree_next(runq_event); while (((struct runq_work*) itree_get(runq_event))->expired) itree_next(runq_event); if (itree_getkey(runq_event) != now+5) { elog_die(FATAL, "[1f] Second queued at an incorrect time\n"); } job_clear(); if (runq_nsched() > 0) { elog_die(FATAL, "[1f] Still active work scheduled. runq_events=%d, " "runq_tab=%d runq_nsched()=%d\n", itree_n(runq_event), itree_n(runq_tab), runq_nsched()); runq_dump(); } now = time(NULL); /* Two 5 run jobs, scheduled to start 100 seconds ago, with periods * of 5 and 6 seconds; they should never be scheduled */ if (job_add(-100, 6, 0, 5, "test1g1", "internal_test", "stdout", "stderr", 100, "exec", "echo \"Hello, world\"") == -1) { elog_die(FATAL, "[1g] Can't add first\n"); } if (job_add(-100, 5, 0, 5, "test1g2", "internal_test", "stdout", "stderr", 100, "exec", "echo \"Hello, world\"") == -1) { elog_die(FATAL, "[1g] Can't add second\n"); } if (runq_nsched() > 0) { elog_die(FATAL, "[1g] Still active work scheduled. runq_events=%d, " "runq_tab=%d runq_nsched()=%d\n", itree_n(runq_event), itree_n(runq_tab), runq_nsched()); runq_dump(); } job_clear(); now = time(NULL); /* Two five run tests, starting at different times in the past, * five runs each wittth different periods; they should both * run now */ if (job_add(-24, 6, 0, 5, "test1h1", "internal_test", "stdout", "stderr", 100, "exec", "echo \"Hello, world\"") == -1) { elog_die(FATAL, "[1h] Can't add first\n"); } if (job_add(-20, 5, 0, 5, "test1h2", "internal_test", "stdout", "stderr", 100, "exec", "echo \"Hello, world\"") == -1) { elog_die(FATAL, "[1h] Can't add second\n"); } if (runq_nsched() != 2) { elog_die(FATAL, "[1h] Two jobs should be scheduled not %d\n", runq_nsched()); runq_dump(); } sig_on(); sleep(6); /* let it run */ sleep(1); /* let it run */ sleep(1); /* let it run */ sleep(1); /* let it run */ sig_off(); if (runq_nsched() > 0) { elog_die(FATAL, "[1h] Still active work scheduled. runq_events=%d, " "runq_tab=%d runq_nsched()=%d\n", itree_n(runq_event), itree_n(runq_tab), runq_nsched()); runq_dump(); } job_clear(); #if 0 /* check all tables/lists are empty */ if (!itree_empty(runq_event) || !itree_empty(runq_tab)) { elog_die(FATAL, "[1i] Still entries in tables. runq_events=%d, " "runq_tab=%d runq_nsched()=%d\n", itree_n(runq_event), itree_n(runq_tab), runq_nsched()); runq_dump(); } #endif job_fini(); meth_fini(); runq_fini(); elog_fini(); route_fini(); callback_fini(); printf("%s: tests finished\n", argv[0]); exit(0); }
char* signature() const {return ((char*) &_sig_off) + sig_off();}