void log_generic(enum LogLevel level, void *ctx, const char *fmt, ...) { char buf[2048], buf2[2048]; char ebuf[256]; char timebuf[64]; const struct LevelInfo *lev = &log_level_list[level]; unsigned pid = getpid(); va_list ap; int pfxlen = 0; int old_errno = errno; char *msg = buf; if (logging_prefix_cb) { pfxlen = logging_prefix_cb(level, ctx, buf, sizeof(buf)); if (pfxlen < 0) goto done; if (pfxlen >= (int)sizeof(buf)) pfxlen = sizeof(buf) - 1; } va_start(ap, fmt); vsnprintf(buf + pfxlen, sizeof(buf) - pfxlen, fmt, ap); va_end(ap); /* replace '\n' in message with '\n\t', strip trailing whitespace */ if (strchr(msg, '\n')) { char *dst = buf2; for (; *msg && dst - buf < (int)sizeof(buf2) - 2; msg++) { *dst++ = *msg; if (*msg == '\n') *dst++ = '\t'; } while (dst > buf2 && isspace(dst[-1])) dst--; *dst = 0; msg = buf2; } format_time_ms(0, timebuf, sizeof(timebuf)); if (!log_file && cf_logfile && cf_logfile[0]) { log_file = fopen(cf_logfile, "a"); if (log_file) { /* Got the file, disable buffering */ setvbuf(log_file, NULL, _IONBF, 0); } else { /* Unable to open, complain and fail */ fprintf(stderr, "%s %u %s Cannot open logfile: '%s': %s\n", timebuf, pid, log_level_list[0].tag, cf_logfile, strerror_r(errno, ebuf, sizeof(ebuf))); exit(1); } } if (!cf_quiet && level <= cf_stderr_level) fprintf(stderr, "%s %u %s %s\n", timebuf, pid, lev->tag, msg); if (log_file && level <= cf_logfile_level) fprintf(log_file, "%s %u %s %s\n", timebuf, pid, lev->tag, msg); if (cf_syslog && level <= cf_syslog_level) { if (!syslog_started) start_syslog(); syslog(lev->syslog_prio, "%s", msg); } done: if (old_errno != errno) errno = old_errno; }
int main(int argc, char **argv) { int err = 0; int id2 = 0, c; double yk = 0.0; /* controller output */ int target_tz_index; if (geteuid() != 0) { printf("TMON needs to be run as root\n"); exit(EXIT_FAILURE); } while ((c = getopt_long(argc, argv, "c:dlht:vgz:", opts, &id2)) != -1) { switch (c) { case 'c': no_control = 0; strncpy(ctrl_cdev, optarg, CDEV_NAME_SIZE); break; case 'd': start_daemon_mode(); printf("Run TMON in daemon mode\n"); break; case 't': ticktime = strtod(optarg, NULL); if (ticktime < 1) ticktime = 1; break; case 'l': printf("Logging data to /var/tmp/tmon.log\n"); logging = 1; break; case 'h': usage(); break; case 'v': version(); break; case 'g': debug_on = 1; break; case 'z': target_thermal_zone = strtod(optarg, NULL); break; default: break; } } if (pthread_mutex_init(&input_lock, NULL) != 0) { fprintf(stderr, "\n mutex init failed, exit\n"); return 1; } start_syslog(); if (signal(SIGINT, tmon_sig_handler) == SIG_ERR) syslog(LOG_DEBUG, "Cannot handle SIGINT\n"); if (signal(SIGTERM, tmon_sig_handler) == SIG_ERR) syslog(LOG_DEBUG, "Cannot handle SIGINT\n"); if (probe_thermal_sysfs()) { pthread_mutex_destroy(&input_lock); closelog(); return -1; } initialize_curses(); setup_windows(); signal(SIGWINCH, resize_handler); show_title_bar(); show_sensors_w(); show_cooling_device(); update_thermal_data(); show_data_w(); prepare_logging(); init_thermal_controller(); nodelay(stdscr, TRUE); err = pthread_create(&event_tid, NULL, &handle_tui_events, NULL); if (err != 0) { printf("\ncan't create thread :[%s]", strerror(err)); tmon_cleanup(); exit(EXIT_FAILURE); } /* validate range of user selected target zone, default to the first * instance if out of range */ target_tz_index = zone_instance_to_index(target_thermal_zone); if (target_tz_index < 0) { target_thermal_zone = ptdata.tzi[0].instance; syslog(LOG_ERR, "target zone is not found, default to %d\n", target_thermal_zone); } while (1) { sleep(ticktime); show_title_bar(); show_sensors_w(); update_thermal_data(); if (!dialogue_on) { show_data_w(); show_cooling_device(); } cur_thermal_record++; time_elapsed += ticktime; controller_handler(trec[0].temp[target_tz_index] / 1000, &yk); trec[0].pid_out_pct = yk; if (!dialogue_on) show_control_w(); if (tmon_exit) break; } tmon_cleanup(); return 0; }