int main(int argc, char **argv) { int retval; boolean_t tty; /* Parse arguments. */ top_p_opts_parse(argc, argv); tty = isatty(0); /* * Make sure the user doesn't mind logging mode, if not running on a * tty. */ if (tty == FALSE && top_opt_L) { fprintf(stderr, "top: Not running on a tty\n"); exit(1); } /* Determine whether to run interactively or in logging mode. */ if (tty && top_opt_l == FALSE) { /* Run interactively. */ if (disp_run()) { retval = 1; goto RETURN; } } else { /* Run in logging mode. */ if (log_run()) { retval = 1; goto RETURN; } } retval = 0; RETURN: return retval; }
int main(int argc, char** argv) { int wstat, ret; pid_t pid; struct timeval tv; service_t *svc; // initialize wake structure, which is owned by main memset(wake, 0, sizeof(*wake)); // just in case, but probably redundant FD_ZERO(&wake->fd_read); FD_ZERO(&wake->fd_write); FD_ZERO(&wake->fd_err); FD_ZERO(&wake->fd_ready_read); FD_ZERO(&wake->fd_ready_write); FD_ZERO(&wake->fd_ready_err); // wake structure holds current time so we don't keep calling clock_gettime() wake->now= gettime_mon_frac(); log_init(); svc_init(); fd_init(); ctl_init(); // Special defaults when running as init if (getpid() == 1) { opt_config_file= CONFIG_FILE_DEFAULT_PATH; opt_terminate_guard= 1; } umask(077); // parse arguments, overriding default values parse_opts(argv+1); // Check for required options if (!opt_interactive && !opt_config_file && !opt_socket_path) fatal(EXIT_BAD_OPTIONS, "require -i or -c or -S"); // Initialize file descriptor object pool if (opt_fd_pool_count > 0 && opt_fd_pool_size_each > 0) if (!fd_preallocate(opt_fd_pool_count, opt_fd_pool_size_each)) fatal(EXIT_INVALID_ENVIRONMENT, "Unable to preallocate file descriptor objects"); if (!fd_init_special_handles()) fatal(EXIT_BROKEN_PROGRAM_STATE, "Can't initialize all special handles"); if (!register_open_fds()) fatal(EXIT_BAD_OPTIONS, "Not enough FD objects to register all open FDs"); // Set up signal handlers and signal mask and signal self-pipe // Do this AFTER registering all open FDs, because it creates a pipe sig_init(); // Initialize service object pool if (opt_svc_pool_count > 0 && opt_svc_pool_size_each > 0) if (!svc_preallocate(opt_svc_pool_count, opt_svc_pool_size_each)) fatal(EXIT_INVALID_ENVIRONMENT, "Unable to preallocate service objects"); // Initialize controller object pool control_socket_init(); if (opt_socket_path && !control_socket_start(STRSEG(opt_socket_path))) fatal(EXIT_INVALID_ENVIRONMENT, "Can't create controller socket"); if (opt_interactive) if (!setup_interactive_mode()) fatal(EXIT_INVALID_ENVIRONMENT, "stdin/stdout are not usable!"); if (opt_config_file) if (!setup_config_file(opt_config_file)) fatal(EXIT_INVALID_ENVIRONMENT, "Unable to process config file"); if (opt_mlockall) { // Lock all memory into ram. init should never be "swapped out". if (mlockall(MCL_CURRENT | MCL_FUTURE)) log_error("mlockall: %s", strerror(errno)); } // fork and setsid if requested, but not if PID 1 or interactive if (opt_daemonize) { if (getpid() == 1 || opt_interactive) log_warn("Ignoring --daemonize (see manual)"); else daemonize(); } // terminate is disabled when running as init, so this is an infinite loop // (except when debugging) wake->now= gettime_mon_frac(); while (!main_terminate) { // set our wait parameters so other methods can inject new wake reasons wake->next= wake->now + (200LL<<32); // wake at least every 200 seconds wake->max_fd= -1; log_run(); // collect new signals since last iteration and set read-wake on signal fd sig_run(); // reap all zombies, possibly waking services while ((pid= waitpid(-1, &wstat, WNOHANG)) > 0) { log_trace("waitpid found pid = %d", (int)pid); if ((svc= svc_by_pid(pid))) svc_handle_reaped(svc, wstat); else log_trace("pid does not belong to any service"); } if (pid < 0) log_trace("waitpid: %s", strerror(errno)); // run state machine of each service that is active. svc_run_active(); // possibly accept new controller connections control_socket_run(); // run controller state machines ctl_run(); log_run(); // Wait until an event or the next time a state machine needs to run // (state machines edit wake.next) wake->now= gettime_mon_frac(); if (wake->next - wake->now > 0) { tv.tv_sec= (long)((wake->next - wake->now) >> 32); tv.tv_usec= (long)((((wake->next - wake->now)&0xFFFFFFFFLL) * 1000000) >> 32); log_trace("wait up to %d.%d sec", tv.tv_sec, tv.tv_usec); } else
static void server_run(void) { analy_run(); monitor_run(); log_run(); }