int eio_open(std::string fname, std::ifstream & in) { int target_big_endian = (endian_host_byte_order() == endian_big); in.open(fname.c_str()); if(!in.is_open()) { fatal("unable to open EIO file `%s'", fname.c_str()); } std::string format_header("/* file_format: 2, file_version: 3, big_endian: 0 */"); std::string format_header_4("/* file_format: 2, file_version: 4, big_endian: 0 */"); std::string start_header("/* ** start checkpoint @ -1... */"); std::string buf; getline(in,buf); buf += '\n'; if(buf!=EIO_FILE_HEADER) { std::cerr << "Failed reading EIO file header, read: " << buf << std::endl; std::cerr << "Should have read: " << EIO_FILE_HEADER << std::endl; exit(-1); } getline(in,buf); getline(in,buf); if(buf!=format_header && buf!=format_header_4) { std::cerr << "Failed reading format header, read: " << buf << std::endl; std::cerr << "Should have read: " << format_header << std::endl; std::cerr << "or: " << format_header_4 << std::endl; exit(-1); } int file_format, file_version, big_endian; char c_buf; in >> c_buf >> file_format >> c_buf >> file_version >> c_buf >> big_endian; getline(in,buf); if(!in.good()) { fatal("could not read EIO file header"); } getline(in,buf); getline(in,buf); if(buf!=start_header) { std::cerr << "Failed reading start header, read: " << buf << std::endl; std::cerr << "Should have read: " << start_header << std::endl; exit(-1); } getline(in,buf); if(file_format != MD_EIO_FILE_FORMAT) { fatal("EIO file `%s' has incompatible format", fname.c_str()); } if((file_version != EIO_FILE_VERSION) && (file_version != EIO_FILE_VERSION_NEW)) { fatal("EIO file `%s' has incompatible version", fname.c_str()); } if(!!big_endian != !!target_big_endian) { warn("endian of `%s' does not match host", fname.c_str()); warn("running with experimental cross-endian execution support"); warn("****************************************"); warn("**>> please check results carefully <<**"); warn("****************************************"); } return file_version; }
void logger::dolog_msg(const logger::msg& a_msg) { try { switch (a_msg.m_type) { case payload_t::CHAR_FUN: { assert(a_msg.m_fun.cf); char buf[4096]; auto* end = buf + sizeof(buf); char* p = format_header(a_msg, buf, end); int n = (a_msg.m_fun.cf)(p, end - p); if (p[n-1] == '\n') --p; p = format_footer(a_msg, p+n, end); m_sig_slot[level_to_signal_slot(a_msg.level())]( on_msg_delegate_t::invoker_type(a_msg, buf, p - buf)); if (fatal_kill_signal() && a_msg.level() == LEVEL_FATAL) { m_abort = true; dolog_fatal_msg(buf, p - buf); } break; } case payload_t::STR_FUN: { assert(a_msg.m_fun.cf); char pfx[256], sfx[256]; char* p = format_header(a_msg, pfx, pfx + sizeof(pfx)); char* q = format_footer(a_msg, sfx, sfx + sizeof(sfx)); auto res = (a_msg.m_fun.sf)(pfx, p - pfx, sfx, q - sfx); m_sig_slot[level_to_signal_slot(a_msg.level())]( on_msg_delegate_t::invoker_type(a_msg, res.c_str(), res.size())); if (fatal_kill_signal() && a_msg.level() == LEVEL_FATAL) { m_abort = true; dolog_fatal_msg(res.c_str(), res.size()); } break; } case payload_t::STR: { detail::basic_buffered_print<1024> buf; char pfx[256], sfx[256]; char* p = format_header(a_msg, pfx, pfx + sizeof(pfx)); char* q = format_footer(a_msg, sfx, sfx + sizeof(sfx)); auto ps = p - pfx; auto qs = q - sfx; buf.reserve(a_msg.m_fun.str.size() + ps + qs + 1); buf.sprint(pfx, ps); auto& s = a_msg.m_fun.str; // Remove trailing new lines auto sz = int(s.size()); while (sz && s[sz-1] == '\n') --sz; buf.sprint(s.c_str(), sz); buf.sprint(sfx, qs); m_sig_slot[level_to_signal_slot(a_msg.level())]( on_msg_delegate_t::invoker_type(a_msg, buf.str(), buf.size())); if (fatal_kill_signal() && a_msg.level() == LEVEL_FATAL) { m_abort = true; dolog_fatal_msg(buf.c_str(), buf.size()); } break; } } } catch (std::runtime_error& e) { if (m_error) m_error(e.what()); else throw; } }
int main(int argc, char *argv[]) { char *env_top; char **preset_argv; int preset_argc = 0; void *mask; int need_mini = 1; struct statics statics; globalstate *gstate; /* get our name */ if (argc > 0) { if ((myname = strrchr(argv[0], '/')) == 0) { myname = argv[0]; } else { myname++; } } /* binary compatibility check */ #ifdef HAVE_UNAME { struct utsname uts; if (uname(&uts) == 0) { if (strcmp(uts.machine, UNAME_HARDWARE) != 0) { fprintf(stderr, "%s: incompatible hardware platform\n", myname); exit(EX_UNAVAILABLE); } } } #endif /* initialization */ gstate = (globalstate *)calloc(1, sizeof(globalstate)); gstate->statics = &statics; time_mark(NULL); /* preset defaults for various options */ gstate->show_usernames = Yes; gstate->topn = DEFAULT_TOPN; gstate->delay = DEFAULT_DELAY; gstate->fulldraw = Yes; gstate->use_color = Yes; gstate->interactive = Maybe; /* preset defaults for process selection */ gstate->pselect.idle = Yes; gstate->pselect.system = No; gstate->pselect.fullcmd = No; gstate->pselect.command = NULL; gstate->pselect.uid = -1; gstate->pselect.mode = 0; /* use a large buffer for stdout */ #ifdef HAVE_SETVBUF setvbuf(stdout, stdoutbuf, _IOFBF, BUFFERSIZE); #else #ifdef HAVE_SETBUFFER setbuffer(stdout, stdoutbuf, BUFFERSIZE); #endif #endif /* get preset options from the environment */ if ((env_top = getenv("TOP")) != NULL) { preset_argv = argparse(env_top, &preset_argc); preset_argv[0] = myname; do_arguments(gstate, preset_argc, preset_argv); } /* process arguments */ do_arguments(gstate, argc, argv); #ifdef ENABLE_COLOR /* If colour has been turned on read in the settings. */ env_top = getenv("TOPCOLOURS"); if (!env_top) { env_top = getenv("TOPCOLORS"); } /* must do something about error messages */ color_env_parse(env_top); color_activate(gstate->use_color); #endif /* in order to support forward compatability, we have to ensure that the entire statics structure is set to a known value before we call machine_init. This way fields that a module does not know about will retain their default values */ memzero((void *)&statics, sizeof(statics)); statics.boottime = -1; /* call the platform-specific init */ if (machine_init(&statics) == -1) { exit(EX_SOFTWARE); } /* create a helper list of sort order names */ gstate->order_namelist = string_list(statics.order_names); /* look up chosen sorting order */ if (gstate->order_name != NULL) { int i; if (statics.order_names == NULL) { message_error(" This platform does not support arbitrary ordering"); } else if ((i = string_index(gstate->order_name, statics.order_names)) == -1) { message_error(" Sort order `%s' not recognized", gstate->order_name); message_error(" Recognized sort orders: %s", gstate->order_namelist); } else { gstate->order_index = i; } } /* initialize extensions */ init_username(); /* initialize termcap */ gstate->smart_terminal = screen_readtermcap(gstate->interactive); /* determine interactive state */ if (gstate->interactive == Maybe) { gstate->interactive = smart_terminal; } /* if displays were not specified, choose an appropriate default */ if (gstate->displays == 0) { gstate->displays = gstate->smart_terminal ? Infinity: 1; } /* we don't need a mini display when delay is less than 2 seconds or when we are not on a smart terminal */ if (gstate->delay <= 1 || !smart_terminal) { need_mini = 0; } /* set constants for username/uid display */ if (gstate->show_usernames) { gstate->header_text = format_header("USERNAME"); gstate->get_userid = username; } else { gstate->header_text = format_header(" UID "); gstate->get_userid = itoa7; } gstate->pselect.usernames = gstate->show_usernames; /* initialize display */ if ((gstate->max_topn = display_init(&statics)) == -1) { fprintf(stderr, "%s: can't allocate sufficient memory\n", myname); exit(EX_OSERR); } /* check for infinity and for overflowed screen */ if (gstate->topn == Infinity) { gstate->topn = INT_MAX; } else if (gstate->topn > gstate->max_topn) { #if 0 message_error(" This terminal can only display %d processes", gstate->max_topn); #endif } #ifdef ENABLE_COLOR /* producing a list of color tags is easy */ if (gstate->show_tags) { color_dump(stdout); exit(EX_OK); } #endif /* hold all signals while we initialize the screen */ mask = hold_signals(); screen_init(); /* set the signal handlers */ set_signals(); /* longjmp re-entry point */ /* set the jump buffer for long jumps out of signal handlers */ if (setjmp(jmp_int) != 0) { /* this is where we end up after processing sigwinch or sigtstp */ /* tell display to resize its buffers, and get the new length */ if ((gstate->max_topn = display_resize()) == -1) { /* thats bad */ quit(EX_OSERR); /*NOTREACHED*/ } /* set up for a full redraw, and get the current line count */ gstate->fulldraw = Yes; /* safe to release the signals now */ release_signals(mask); } else { /* release the signals */ release_signals(mask); /* some systems require a warmup */ /* always do a warmup for batch mode */ if (gstate->interactive == 0 || statics.flags.warmup) { struct system_info system_info; struct timeval timeout; time_mark(&(gstate->now)); get_system_info(&system_info); (void)get_process_info(&system_info, &gstate->pselect, 0); timeout.tv_sec = 1; timeout.tv_usec = 0; select(0, NULL, NULL, NULL, &timeout); /* if we've warmed up, then we can show good states too */ gstate->show_cpustates = Yes; need_mini = 0; } } /* main loop */ while ((gstate->displays == -1) || (--gstate->displays > 0)) { do_display(gstate); if (gstate->interactive) { if (need_mini) { do_minidisplay(gstate); need_mini = 0; } do_command(gstate); } else { do_wait(gstate); } } /* do one last display */ do_display(gstate); quit(EX_OK); /* NOTREACHED */ return 1; /* Keep compiler quiet. */ }
void logger::run() { utxx::signal_block block_signals(m_block_signals); if (m_on_before_run) m_on_before_run(); if (!m_ident.empty()) pthread_setname_np(pthread_self(), m_ident.c_str()); int event_val; do { event_val = m_event.value(); //wakeup_result rc = wakeup_result::TIMEDOUT; while (!m_abort && m_queue.empty()) { m_event.wait(&m_wait_timeout, &event_val); ASYNC_DEBUG_TRACE( (" %s LOGGER awakened (res=%s, val=%d, futex=%d), abort=%d, head=%s\n", timestamp::to_string().c_str(), to_string(rc).c_str(), event_val, m_event.value(), m_abort, m_queue.empty() ? "empty" : "data") ); } // When running with maximum priority, occasionally excessive use of // sched_yield may use to system slowdown, so this option is // configurable by m_sched_yield_us: if (m_queue.empty() && m_sched_yield_us >= 0) { time_val deadline(rel_time(0, m_sched_yield_us)); while (m_queue.empty()) { if (m_abort) goto DONE; if (now_utc() > deadline) break; sched_yield(); } } // Get all pending items from the queue for (auto* item = m_queue.pop_all(), *next=item; item; item = next) { next = item->next(); try { dolog_msg(item->data()); } catch ( std::exception const& e ) { // Unhandled error writing data to some destination // Print error report to stderr (can't do anything better -- // the error happened in the m_on_error callback!) const msg msg(LEVEL_INFO, "", std::string("Fatal exception in logger"), UTXX_LOG_SRCINFO); detail::basic_buffered_print<1024> buf; char pfx[256], sfx[256]; char* p = format_header(msg, pfx, pfx + sizeof(pfx)); char* q = format_footer(msg, sfx, sfx + sizeof(sfx)); auto ps = p - pfx; auto qs = q - sfx; buf.reserve(msg.m_fun.str.size() + ps + qs + 1); buf.sprint(pfx, ps); buf.print(msg.m_fun.str); buf.sprint(sfx, qs); std::cerr << buf.str() << std::endl; m_abort = true; // TODO: implement attempt to store transient messages to some // other medium // Free all pending messages while (item) { m_queue.free(item); item = next; next = item->next(); } goto DONE; } m_queue.free(item); item = next; } } while (!m_abort); DONE: if (!m_silent_finish) { const msg msg(LEVEL_INFO, "", std::string("Logger thread finished"), UTXX_LOG_SRCINFO); try { dolog_msg(msg); } catch (...) {} } if (m_on_after_run) m_on_after_run(); }