/* ------------------------------------------------------------ err_param.c (init_errors) : calls : err_param.c (open_error_log), stdlib.h (malloc, free) , stdio.h (fprintf, fflush) stdlib.h (malloc,free) --------------------------------------------------------------*/ ERR_PARAM *init_errors( PAGC_GLOBAL *pagc_glo_p , const char *log_name ) { ERR_PARAM *err_p ; ERR_REC *err_mem ; err_p = ( ERR_PARAM * ) malloc( sizeof( ERR_PARAM ) ) ; if ( err_p == NULL ) { #ifndef NO_STDERR_OUTPUT PRINT_ERROR( "%s\n" , "FATAL ERROR : Could not allocate memory for pagc_init_errors" ) ; #endif return NULL ; } /* -- set up first record -- */ RESET_ERR_P ; /* -- a null log_name means we don't log , but collect -- */ if ( log_name == NULL ) { err_p -> stream = NULL ; } else { err_p -> stream = open_error_log( log_name , pagc_glo_p -> _file_sys , err_p ) ; if ( err_p -> stream == NULL ) { FREE_AND_NULL( err_p ) ; #ifndef NO_STDERR_OUTPUT PRINT_ERROR( "Could not create error log for pathname: %s\n" , log_name ) ; #endif return NULL ; } } return err_p ; }
void ap_open_logs (server_rec *s_main, pool *p) { server_rec *virt, *q; int replace_stderr; open_error_log (s_main, p); replace_stderr = 1; if (s_main->error_log) { /* replace stderr with this new log */ fflush(stderr); if (dup2(fileno(s_main->error_log), 2) == -1) { ap_log_error(APLOG_MARK, APLOG_CRIT, s_main, "unable to replace stderr with error_log"); } else { replace_stderr = 0; } } /* note that stderr may still need to be replaced with something * because it points to the old error log, or back to the tty * of the submitter. */ if (replace_stderr && freopen("/dev/null", "w", stderr) == NULL) { ap_log_error(APLOG_MARK, APLOG_CRIT, s_main, "unable to replace stderr with /dev/null"); } for (virt = s_main->next; virt; virt = virt->next) { if (virt->error_fname) { for (q=s_main; q != virt; q = q->next) if (q->error_fname != NULL && strcmp(q->error_fname, virt->error_fname) == 0) break; if (q == virt) open_error_log (virt, p); else virt->error_log = q->error_log; } else virt->error_log = s_main->error_log; } }
int ap_open_logs(apr_pool_t *pconf, apr_pool_t *p /* plog */, apr_pool_t *ptemp, server_rec *s_main) { apr_status_t rc = APR_SUCCESS; server_rec *virt, *q; int replace_stderr; apr_file_t *errfile = NULL; apr_pool_cleanup_register(p, NULL, clear_handle_list, apr_pool_cleanup_null); if (open_error_log(s_main, 1, p) != OK) { return DONE; } replace_stderr = 1; if (s_main->error_log) { /* replace stderr with this new log */ apr_file_flush(s_main->error_log); if ((rc = apr_file_open_stderr(&errfile, p)) == APR_SUCCESS) { rc = apr_file_dup2(errfile, s_main->error_log, p); } if (rc != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_CRIT, rc, s_main, "unable to replace stderr with error_log"); } else { replace_stderr = 0; } } /* note that stderr may still need to be replaced with something * because it points to the old error log, or back to the tty * of the submitter. * XXX: This is BS - /dev/null is non-portable */ if (replace_stderr && freopen("/dev/null", "w", stderr) == NULL) { ap_log_error(APLOG_MARK, APLOG_CRIT, errno, s_main, "unable to replace stderr with /dev/null"); } for (virt = s_main->next; virt; virt = virt->next) { if (virt->error_fname) { for (q=s_main; q != virt; q = q->next) { if (q->error_fname != NULL && strcmp(q->error_fname, virt->error_fname) == 0) { break; } } if (q == virt) { if (open_error_log(virt, 0, p) != OK) { return DONE; } } else { virt->error_log = q->error_log; } } else { virt->error_log = s_main->error_log; } } return OK; }
int main(int argc, char *argv[]) { extern char *optarg; extern int optind, opterr, optopt; int c, aout = 0; char *fcode_file = NULL; char *forthstr = NULL; int debug = 0; int syslog_flags = MSG_SYSLOG_DEFAULT; int lflag = 0; int error_log_flags; char *errlog = NULL; extern void run_one_efdaemon_request(fcode_env_t *); common.Progname = argv[0]; common.search_path = getenv("FC_SEARCH_PATH"); common.fcode_fd = -1; env = fc_env = clone_environment(NULL, &common); while ((c = getopt(argc, argv, "ad:e:f:l:iDs:k")) != EOF) { switch (c) { case 'a': aout = 1; break; case 'd': debug = debug_flags_to_mask(optarg); set_interpreter_debug_level(debug); if (debug) env->fcode_debug = 1; break; case 'e': if ((errlog = strchr(optarg, ':')) != NULL) { *errlog++ = '\0'; error_log_flags = parse_msg_flags(optarg); } else { errlog = optarg; error_log_flags = MSG_ERRLOG_DEFAULT; } open_error_log(errlog, error_log_flags); break; case 'l': syslog_flags = parse_msg_flags(optarg); lflag++; break; case 'D': env->fcode_debug = 1; break; case 'f': fcode_file = optarg; break; case 'i': forthstr = "interact"; env->fcode_debug = 1; break; case 's': forthstr = optarg; break; case '?': usage(argv); exit(1); } } if (forthstr) { run_fcode(env, (uchar_t *)forthstr, strlen(forthstr)); } else if (fcode_file) { run_fcode_from_file(env, fcode_file, aout); } else { if ((debug & DEBUG_FC_LIST) != 0 && ((error_log_flags | syslog_flags) & MSG_FC_DEBUG) == 0) { log_message(MSG_WARN, "Warning, verbose debug flag(s)" " on, but syslog/errlog not enabled for verbose" " debug\n"); if (errlog) error_log_flags |= MSG_FC_DEBUG; else syslog_flags |= MSG_FC_DEBUG; } if ((debug & ~DEBUG_FC_LIST) != 0 && ((error_log_flags | syslog_flags) & MSG_DEBUG) == 0) { log_message(MSG_WARN, "Warning, debug flag(s) on, but" " syslog/errlog not enabled for debug\n"); if (errlog) error_log_flags |= MSG_DEBUG; else syslog_flags |= MSG_DEBUG; } if (errlog == NULL || lflag) { if (syslog_flags & MSG_FC_DEBUG) log_message(MSG_WARN, "Warning, verbose debug" " not recommended for syslog\n"); open_syslog_log("interpreter", syslog_flags); } run_one_efdaemon_request(env); } return (0); }
int ap_open_logs(apr_pool_t *pconf, apr_pool_t *p /* plog */, apr_pool_t *ptemp, server_rec *s_main) { apr_pool_t *stderr_p; server_rec *virt, *q; int replace_stderr; /* Register to throw away the read_handles list when we * cleanup plog. Upon fork() for the apache children, * this read_handles list is closed so only the parent * can relaunch a lost log child. These read handles * are always closed on exec. * We won't care what happens to our stderr log child * between log phases, so we don't mind losing stderr's * read_handle a little bit early. */ apr_pool_cleanup_register(p, NULL, clear_handle_list, apr_pool_cleanup_null); /* HERE we need a stdout log that outlives plog. * We *presume* the parent of plog is a process * or global pool which spans server restarts. * Create our stderr_pool as a child of the plog's * parent pool. */ apr_pool_create(&stderr_p, apr_pool_parent_get(p)); apr_pool_tag(stderr_p, "stderr_pool"); if (open_error_log(s_main, 1, stderr_p) != OK) { return DONE; } replace_stderr = 1; if (s_main->error_log) { apr_status_t rv; /* Replace existing stderr with new log. */ apr_file_flush(s_main->error_log); rv = apr_file_dup2(stderr_log, s_main->error_log, stderr_p); if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s_main, "unable to replace stderr with error_log"); } else { /* We are done with stderr_pool, close it, killing * the previous generation's stderr logger */ if (stderr_pool) apr_pool_destroy(stderr_pool); stderr_pool = stderr_p; replace_stderr = 0; /* * Now that we have dup'ed s_main->error_log to stderr_log * close it and set s_main->error_log to stderr_log. This avoids * this fd being inherited by the next piped logger who would * keep open the writing end of the pipe that this one uses * as stdin. This in turn would prevent the piped logger from * exiting. */ apr_file_close(s_main->error_log); s_main->error_log = stderr_log; } } /* note that stderr may still need to be replaced with something * because it points to the old error log, or back to the tty * of the submitter. * XXX: This is BS - /dev/null is non-portable */ if (replace_stderr && freopen("/dev/null", "w", stderr) == NULL) { ap_log_error(APLOG_MARK, APLOG_CRIT, errno, s_main, "unable to replace stderr with /dev/null"); } for (virt = s_main->next; virt; virt = virt->next) { if (virt->error_fname) { for (q=s_main; q != virt; q = q->next) { if (q->error_fname != NULL && strcmp(q->error_fname, virt->error_fname) == 0) { break; } } if (q == virt) { if (open_error_log(virt, 0, p) != OK) { return DONE; } } else { virt->error_log = q->error_log; } } else { virt->error_log = s_main->error_log; } } return OK; }
/* server_main() * -> sb_run_* APIs are enabled * -> all registries are enabled * -> all configs are enabled. config should follow and overwrite registry. */ int server_main() { module *mod=NULL; /*********************************************************************** * first-pass config */ set_proc_desc(NULL, "softbotd: master - loading static modules"); /* load_static_modules() * -> hooking APIs. we cannot call sb_run_* APIs before this */ load_static_modules(); /* FIXME why should i load kbo module?? */ //load_kbo_module(); if (read_config(mConfigFile, NULL) != SUCCESS) { crit("failed to read config file"); exit(1); } /* 1. load dynamic modules -> make linked list of whole modules * 2. setup each modules's configuration -> call each config function */ open_error_log(gErrorLogFile, gQueryLogFile); #ifdef USE_TIMELOG if(sb_tstat_log_init(mTimeLogFile) != SUCCESS) { exit(1); } #endif save_pid(mPidFile); load_dynamic_modules(); /*********************************************************************** * all the modules has been loaded. */ sb_sort_hook(); load_each_registry(); /* 1. register each module to registry * 2. do the shared memory related stuff... * 3. XXX registry module does not guarantee shared memory locking... */ restore_registry_file(gRegistryFile); /* TODO second-pass config */ /*********************************************************************** * runtime configuration is done. */ init_all_scoreboards(); /* method 3 of doc/README.init */ set_proc_desc(NULL, "softbotd: master - init each module"); if ( init_core_modules(first_module) != SUCCESS ) goto STOP; if ( init_standard_modules(first_module) != SUCCESS ) goto STOP; if (clc_listen_port >= 2) { /* show using ports */ show_portinfo(); goto STOP; } set_proc_desc(NULL, "softbotd: master - spawning child"); /* check debug_module */ if ( strlen(debug_module) > 0 ) { mod = find_module(debug_module); if ( mod == NULL ) { error("no such module [%s]", debug_module); return FAIL; } else { info("debugging module [%s]", debug_module); // XXX: in debugging mode, isn't it better not to fork? is it? if (mod->main) sb_run_spawn_process_for_module(scoreboard, mod); else { error("module[%s] has no main",debug_module); exit(1); } } } else if (unittest) { crit("unittesting started"); do_unittest(); crit("unittesting ended"); goto STOP; } else sb_run_spawn_processes_for_each_module(scoreboard, first_module); CRIT("*** master monitoring loop ***"); setproctitle("softbotd: master - monitoring"); set_proc_desc(NULL, "softbotd: master - monitoring"); scoreboard->period = CHILD_MONITORING_PERIOD; sb_run_monitor_processes_for_modules(scoreboard, first_module); /*********************************************************************** * stopping state. */ STOP: if ( save_registry_file(gRegistryFile) != SUCCESS ) error("save_registry_file(%s) failed: %s", gRegistryFile, strerror(errno)); free_ipcs(); /* release shared memory and semaphore */ close_error_log(); /* close error_log file and semaphore */ #ifdef USE_TIMELOG sb_tstat_log_destroy(); #endif return SUCCESS; }