--- projects/libstatgrab/src/saidar/saidar.c 2003/10/09 15:57:05 1.1 +++ projects/libstatgrab/src/saidar/saidar.c 2007/01/05 13:30:36 1.41 @@ -1,3 +1,29 @@ +/* + * i-scream libstatgrab + * http://www.i-scream.org + * Copyright (C) 2000-2004 i-scream + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Id: saidar.c,v 1.41 2007/01/05 13:30:36 tdb Exp $ + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include @@ -10,36 +36,65 @@ #include #include #include -#include +#include +#ifdef HAVE_NCURSES_H +#define COLOR_SUPPORT +#endif +#include CURSES_HEADER_FILE + +#define THRESHOLD_LOAD 1.0 + +#define THRESHOLD_WARN_ZMB 0 + +#define THRESHOLD_WARN_CPU 60.0 +#define THRESHOLD_ALERT_CPU 90.0 + +#define THRESHOLD_WARN_SWAP 75.0 +#define THRESHOLD_ALERT_SWAP 90.0 + +#define THRESHOLD_WARN_MEM 75.0 +#define THRESHOLD_ALERT_MEM 90.0 + +#define THRESHOLD_WARN_DISK 75.0 +#define THRESHOLD_ALERT_DISK 90.0 + +int sig_winch_flag = 0; + typedef struct{ - cpu_percent_t *cpu_percents; - mem_stat_t *mem_stats; - swap_stat_t *swap_stats; - load_stat_t *load_stats; - process_stat_t *process_stats; - page_stat_t *page_stats; + sg_cpu_percents *cpu_percents; + sg_mem_stats *mem_stats; + sg_swap_stats *swap_stats; + sg_load_stats *load_stats; + sg_process_count *process_count; + sg_page_stats *page_stats; - network_stat_t *network_stats; - int network_entries; + sg_network_io_stats *network_io_stats; + int network_io_entries; - diskio_stat_t *diskio_stats; - int diskio_entries; + sg_disk_io_stats *disk_io_stats; + int disk_io_entries; - disk_stat_t *disk_stats; - int disk_entries; + sg_fs_stats *fs_stats; + int fs_entries; - general_stat_t *general_stats; - user_stat_t *user_stats; + sg_host_info *host_info; + sg_user_stats *user_stats; }stats_t; - + stats_t stats; char *size_conv(long long number){ char type[] = {'B', 'K', 'M', 'G', 'T'}; int x=0; + int sign=1; static char string[10]; + if(number < 0){ + sign=-1; + number=-number; + } + for(;x<5;x++){ if( (number/1024) < (100)) { break; @@ -47,16 +102,18 @@ char *size_conv(long long number){ number = (number/1024); } - snprintf(string, 10, "%lld%c", number, type[x]); + number = number*sign; + + snprintf(string, 10, "%lld%c", number, type[x]); return string; - + } char *hr_uptime(time_t time){ int day = 0, hour = 0, min = 0; static char uptime_str[25]; int sec = (int) time; - + day = sec / (24*60*60); sec = sec % (24*60*60); hour = sec / (60*60); @@ -73,6 +130,8 @@ char *hr_uptime(time_t time){ } void display_headings(){ + int line; + move(0,0); printw("Hostname :"); move(0,27); @@ -119,12 +178,12 @@ void display_headings(){ printw("Mem Free :"); /* Swap */ - move(6, 21); - printw("Swap Total:"); - move(7, 21); - printw("Swap Used :"); - move(8, 21); - printw("Swap Free :"); + move(6, 21); + printw("Swap Total:"); + move(7, 21); + printw("Swap Used :"); + move(8, 21); + printw("Swap Free :"); /* VM */ move(6, 42); @@ -146,219 +205,451 @@ void display_headings(){ move(10,15); printw("Read"); move(10,28); - printw("Write"); + printw("Write"); - /* Network IO */ - move(10, 42); - printw("Network Interface"); - move(10, 67); - printw("rx"); - move(10,77); - printw("tx"); + line = 10; + if (stats.network_io_stats != NULL) { + /* Network IO */ + move(line, 42); + printw("Network Interface"); + move(line, 67); + printw("rx"); + move(line, 77); + printw("tx"); + line += 2 + stats.network_io_entries; + } - move(12+stats.network_entries, 42); + move(line, 42); printw("Mount Point"); - move(12+stats.network_entries, 65); + move(line, 65); printw("Free"); - move(12+stats.network_entries, 75); + move(line, 75); printw("Used"); refresh(); } -void display_data(){ +void display_data(int colors){ char cur_time[20]; struct tm *tm_time; time_t epoc_time; - int counter; + int counter, line; long long r,w; long long rt, wt; - diskio_stat_t *diskio_stat_ptr; - network_stat_t *network_stat_ptr; - disk_stat_t *disk_stat_ptr; + sg_disk_io_stats *disk_io_stat_ptr; + sg_network_io_stats *network_stat_ptr; + sg_fs_stats *disk_stat_ptr; + /* Size before it will start overwriting "uptime" */ + char hostname[15]; + char *ptr; - move(0,12); - printw("%s", stats.general_stats->hostname); - move(0,36); - printw("%s", hr_uptime(stats.general_stats->uptime)); - epoc_time=time(NULL); - tm_time = localtime(&epoc_time); - strftime(cur_time, 20, "%Y-%m-%d %T", tm_time); - move(0,61); - printw("%s", cur_time); + if (stats.host_info != NULL) { + move(0,12); + strncpy(hostname, stats.host_info->hostname, (sizeof(hostname) - 1)); + /* strncpy does not NULL terminate.. If only strlcpy was on all platforms :) */ + hostname[14] = '\0'; + ptr=strchr(hostname, '.'); + /* Some hosts give back a FQDN for hostname. To avoid this, we'll + * just blank out everything after the first "." + */ + if (ptr != NULL){ + *ptr = '\0'; + } + if (colors) { + attron(COLOR_PAIR(1)); + } + printw("%s", hostname); + move(0,36); + printw("%s", hr_uptime(stats.host_info->uptime)); + epoc_time=time(NULL); + tm_time = localtime(&epoc_time); + strftime(cur_time, 20, "%Y-%m-%d %T", tm_time); + move(0,61); + printw("%s", cur_time); + if (colors) { + attroff(COLOR_PAIR(1)); + } + } - /* Load */ - move(2,12); - printw("%6.2f", stats.load_stats->min1); - move(3,12); - printw("%6.2f", stats.load_stats->min5); - move(4,12); - printw("%6.2f", stats.load_stats->min15); + if (stats.load_stats != NULL) { + /* Load */ + if (colors) { + attron(COLOR_PAIR(6)); + } + move(2,12); + if (colors && fabs(stats.load_stats->min1 - stats.load_stats->min5) > THRESHOLD_LOAD) { + attron(A_BOLD); + } + printw("%6.2f", stats.load_stats->min1); + if (colors) { + attroff(A_BOLD); + } + move(3,12); + if (colors && fabs(stats.load_stats->min5 - stats.load_stats->min15) > THRESHOLD_LOAD) { + attron(A_BOLD); + } + printw("%6.2f", stats.load_stats->min5); + if (colors) { + attroff(A_BOLD); + } + move(4,12); + if (colors && fabs(stats.load_stats->min1 - stats.load_stats->min15) > THRESHOLD_LOAD) { + attron(A_BOLD); + } + printw("%6.2f", stats.load_stats->min15); + if (colors) { + attroff(A_BOLD); + } + } - /* CPU */ - move(2,33); - printw("%6.2f%%", stats.cpu_percents->idle); - move(3,33); - printw("%6.2f%%", (stats.cpu_percents->kernel + stats.cpu_percents->iowait + stats.cpu_percents->swap)); - move(4,33); - printw("%6.2f%%", (stats.cpu_percents->user + stats.cpu_percents->nice)); + if (stats.cpu_percents != NULL) { + /* CPU */ + move(2,33); + printw("%6.2f%%", stats.cpu_percents->idle); + move(3,33); + printw("%6.2f%%", (stats.cpu_percents->kernel + stats.cpu_percents->iowait + stats.cpu_percents->swap)); + move(4,33); + if (colors && stats.cpu_percents->user + stats.cpu_percents->nice > THRESHOLD_ALERT_CPU) { + attron(A_STANDOUT); + attron(A_BOLD); + } + else if (colors && stats.cpu_percents->user + stats.cpu_percents->nice > THRESHOLD_WARN_CPU) { + attron(A_BOLD); + } + printw("%6.2f%%", (stats.cpu_percents->user + stats.cpu_percents->nice)); + if(colors) { + attroff(A_BOLD); + attroff(A_STANDOUT); + attron(COLOR_PAIR(6)); + } + } - /* Process */ - move(2, 54); - printw("%5d", stats.process_stats->running); - move(2,74); - printw("%5d", stats.process_stats->zombie); - move(3, 54); - printw("%5d", stats.process_stats->sleeping); - move(3, 74); - printw("%5d", stats.process_stats->total); - move(4, 54); - printw("%5d", stats.process_stats->stopped); - move(4,74); - printw("%5d", stats.user_stats->num_entries); + if (stats.process_count != NULL) { + /* Process */ + move(2, 54); + printw("%5d", stats.process_count->running); + move(2,74); + if (colors && stats.process_count->zombie > THRESHOLD_WARN_ZMB) { + attron(A_STANDOUT); + attron(A_BOLD); + } + printw("%5d", stats.process_count->zombie); + if(colors) { + attroff(A_STANDOUT); + attroff(A_BOLD); + } + move(3, 54); + printw("%5d", stats.process_count->sleeping); + move(3, 74); + printw("%5d", stats.process_count->total); + move(4, 54); + printw("%5d", stats.process_count->stopped); + } + if (stats.user_stats != NULL) { + move(4,74); + printw("%5d", stats.user_stats->num_entries); + } - /* Mem */ + if(colors) { + attroff(COLOR_PAIR(6)); + attron(COLOR_PAIR(5)); + } + if (stats.mem_stats != NULL) { + /* Mem */ + move(6, 12); + printw("%7s", size_conv(stats.mem_stats->total)); + move(7, 12); + printw("%7s", size_conv(stats.mem_stats->used)); + move(8, 12); + printw("%7s", size_conv(stats.mem_stats->free)); + } - move(6, 12); - printw("%7s", size_conv(stats.mem_stats->total)); - move(7, 12); - printw("%7s", size_conv(stats.mem_stats->used)); - move(8, 12); - printw("%7s", size_conv(stats.mem_stats->free)); - - /* Swap */ - move(6, 32); - printw("%8s", size_conv(stats.swap_stats->total)); - move(7, 32); - printw("%8s", size_conv(stats.swap_stats->used)); - move(8, 32); - printw("%8s", size_conv(stats.swap_stats->free)); + if (stats.swap_stats != NULL) { + /* Swap */ + move(6, 32); + printw("%8s", size_conv(stats.swap_stats->total)); + move(7, 32); + printw("%8s", size_conv(stats.swap_stats->used)); + move(8, 32); + printw("%8s", size_conv(stats.swap_stats->free)); + } /* VM */ - move(6, 54); - printw("%5.2f%%", (100.00 * (float)(stats.mem_stats->used)/stats.mem_stats->total)); - move(7, 54); - printw("%5.2f%%", (100.00 * (float)(stats.swap_stats->used)/stats.swap_stats->total)); - move(8, 54); - printw("%5.2f%%", (100.00 * (float)(stats.mem_stats->used+stats.swap_stats->used)/(stats.mem_stats->total+stats.swap_stats->total))); + if (stats.mem_stats != NULL && stats.mem_stats->total != 0) { + float f = 100.00 * (float)(stats.mem_stats->used)/stats.mem_stats->total; + if (colors && f > THRESHOLD_ALERT_MEM) { + attron(A_STANDOUT); + attron(A_BOLD); + } + else if (colors && f > THRESHOLD_WARN_MEM) { + attron(A_BOLD); + } + move(6, 54); + printw("%5.2f%%", f); + if (colors) { + attroff(A_STANDOUT); + attroff(A_BOLD); + attron(COLOR_PAIR(5)); + } + } + if (stats.swap_stats != NULL && stats.swap_stats->total != 0) { + float f = 100.00 * (float)(stats.swap_stats->used)/stats.swap_stats->total; + if (colors && f > THRESHOLD_ALERT_SWAP) { + attron(A_STANDOUT); + attron(A_BOLD); + } + else if (colors && f > THRESHOLD_WARN_SWAP) { + attron(A_BOLD); + } + move(7, 54); + printw("%5.2f%%", f); + if (colors) { + attroff(A_STANDOUT); + attroff(A_BOLD); + attron(COLOR_PAIR(5)); + } + } + if (stats.mem_stats != NULL && stats.swap_stats != NULL && + stats.mem_stats->total != 0 && stats.swap_stats->total != 0) { + move(8, 54); + printw("%5.2f%%", (100.00 * (float)(stats.mem_stats->used+stats.swap_stats->used)/(stats.mem_stats->total+stats.swap_stats->total))); + } - /* Paging */ - move(6, 74); - printw("%5d", (stats.page_stats->systime)? (stats.page_stats->pages_pagein / stats.page_stats->systime): stats.page_stats->pages_pagein); - move(7, 74); - printw("%5d", (stats.page_stats->systime)? (stats.page_stats->pages_pageout / stats.page_stats->systime) : stats.page_stats->pages_pageout); + if (stats.page_stats != NULL) { + /* Paging */ + move(6, 74); + printw("%5d", (stats.page_stats->systime)? (stats.page_stats->pages_pagein / stats.page_stats->systime): stats.page_stats->pages_pagein); + move(7, 74); + printw("%5d", (stats.page_stats->systime)? (stats.page_stats->pages_pageout / stats.page_stats->systime) : stats.page_stats->pages_pageout); + } + if (colors) { + attroff(COLOR_PAIR(5)); + } - /* Disk IO */ - diskio_stat_ptr = stats.diskio_stats; - r=0; - w=0; - for(counter=0;counterdisk_name); - move(11+counter, 12); - rt = (diskio_stat_ptr->systime)? (diskio_stat_ptr->read_bytes/diskio_stat_ptr->systime): diskio_stat_ptr->read_bytes; - printw("%7s", size_conv(rt)); - r+=rt; - move(11+counter, 26); - wt = (diskio_stat_ptr->systime)? (diskio_stat_ptr->write_bytes/diskio_stat_ptr->systime): diskio_stat_ptr->write_bytes; - printw("%7s", size_conv(wt)); - w+=wt; - diskio_stat_ptr++; + line = 11; + if (stats.disk_io_stats != NULL) { + /* Disk IO */ + disk_io_stat_ptr = stats.disk_io_stats; + r=0; + w=0; + for(counter=0;counterdisk_name, sizeof(name)); + name[sizeof(name)-1] = '\0'; /* strncpy doesn't terminate longer strings */ + move(line, 0); + printw("%s", name); + move(line, 12); + rt = (disk_io_stat_ptr->systime)? (disk_io_stat_ptr->read_bytes/disk_io_stat_ptr->systime): disk_io_stat_ptr->read_bytes; + if(colors) { + attron(COLOR_PAIR(4)); + } + printw("%7s", size_conv(rt)); + r+=rt; + move(line, 26); + wt = (disk_io_stat_ptr->systime)? (disk_io_stat_ptr->write_bytes/disk_io_stat_ptr->systime): disk_io_stat_ptr->write_bytes; + printw("%7s", size_conv(wt)); + w+=wt; + disk_io_stat_ptr++; + line++; + if(colors) { + attroff(COLOR_PAIR(4)); + } + } + line++; + move(line, 0); + printw("Total"); + move(line, 12); + if(colors) { + attron(COLOR_PAIR(4)); + } + printw("%7s", size_conv(r)); + move(line, 26); + printw("%7s", size_conv(w)); + if(colors) { + attroff(COLOR_PAIR(4)); + } } - move(12+counter, 0); - printw("Total"); - move(12+counter, 12); - printw("%7s", size_conv(r)); - move(12+counter, 26); - printw("%7s", size_conv(w)); - /* Network */ - network_stat_ptr = stats.network_stats; - for(counter=0;counterinterface_name); - move(11+counter, 62); - rt = (network_stat_ptr->systime)? (network_stat_ptr->rx / network_stat_ptr->systime): network_stat_ptr->rx; - printw("%7s", size_conv(rt)); - move(11+counter, 72); - wt = (network_stat_ptr->systime)? (network_stat_ptr->tx / network_stat_ptr->systime): network_stat_ptr->tx; - printw("%7s", size_conv(wt)); - network_stat_ptr++; + line = 11; + if (stats.network_io_stats != NULL) { + /* Network */ + network_stat_ptr = stats.network_io_stats; + for(counter=0;counterinterface_name, sizeof(name)); + name[sizeof(name)-1] = '\0'; /* strncpy doesn't terminate longer strings */ + move(line, 42); + printw("%s", name); + move(line, 62); + rt = (network_stat_ptr->systime)? (network_stat_ptr->rx / network_stat_ptr->systime): network_stat_ptr->rx; + if(colors) { + attron(COLOR_PAIR(4)); + } + printw("%7s", size_conv(rt)); + move(line, 72); + wt = (network_stat_ptr->systime)? (network_stat_ptr->tx / network_stat_ptr->systime): network_stat_ptr->tx; + printw("%7s", size_conv(wt)); + network_stat_ptr++; + line++; + if(colors) { + attroff(COLOR_PAIR(4)); + } + } + line += 2; } - disk_stat_ptr = stats.disk_stats; - for(counter=0;countermnt_point); - move(13+stats.network_entries+counter, 62); - printw("%7s", size_conv(disk_stat_ptr->avail)); - move(13+stats.network_entries+counter, 73); - printw("%5.2f%%", 100.00 * ((float)disk_stat_ptr->used / (float)disk_stat_ptr->size)); - disk_stat_ptr++; + if (stats.fs_stats != NULL) { + /* Disk */ + disk_stat_ptr = stats.fs_stats; + for(counter=0;countermnt_point, sizeof(name)); + name[sizeof(name)-1] = '\0'; /* strncpy doesn't terminate longer strings */ + move(line, 42); + printw("%s", name); + move(line, 62); + if(colors) { + attron(COLOR_PAIR(2)); + } + printw("%7s", size_conv(disk_stat_ptr->avail)); + move(line, 73); + if(colors && 100.00 * ((float) disk_stat_ptr->used / (float) (disk_stat_ptr->used + disk_stat_ptr->avail)) > THRESHOLD_ALERT_DISK) { + attron(A_STANDOUT); + attron(A_BOLD); + } else if (colors && 100.00 * ((float) disk_stat_ptr->used / (float) (disk_stat_ptr->used + disk_stat_ptr->avail)) > THRESHOLD_WARN_DISK) { + attron(A_BOLD); + } + printw("%6.2f%%", 100.00 * ((float) disk_stat_ptr->used / (float) (disk_stat_ptr->used + disk_stat_ptr->avail))); + disk_stat_ptr++; + line++; + if(colors) { + attroff(COLOR_PAIR(2)); + attroff(A_STANDOUT); + attroff(A_BOLD); + } + } } refresh(); } -void sig_winch_handler(int sig){ - clear(); - display_headings(); - display_data(); - signal(SIGWINCH, sig_winch_handler); +void sig_winch_handler(int dummy){ + sig_winch_flag = 1; + signal(SIGWINCH, sig_winch_handler); } int get_stats(){ - if((stats.cpu_percents = cpu_percent_usage()) == NULL) return 0; - if((stats.mem_stats = get_memory_stats()) == NULL) return 0; - if((stats.swap_stats = get_swap_stats()) == NULL) return 0; - if((stats.load_stats = get_load_stats()) == NULL) return 0; - if((stats.process_stats = get_process_stats()) == NULL) return 0; - if((stats.page_stats = get_page_stats_diff()) == NULL) return 0; - if((stats.network_stats = get_network_stats_diff(&(stats.network_entries))) == NULL) return 0; - if((stats.diskio_stats = get_diskio_stats_diff(&(stats.diskio_entries))) == NULL) return 0; - if((stats.disk_stats = get_disk_stats(&(stats.disk_entries))) == NULL) return 0; - if((stats.general_stats = get_general_stats()) == NULL) return 0; - if((stats.user_stats = get_user_stats()) == NULL) return 0; + stats.cpu_percents = sg_get_cpu_percents(); + stats.mem_stats = sg_get_mem_stats(); + stats.swap_stats = sg_get_swap_stats(); + stats.load_stats = sg_get_load_stats(); + stats.process_count = sg_get_process_count(); + stats.page_stats = sg_get_page_stats_diff(); + stats.network_io_stats = sg_get_network_io_stats_diff(&(stats.network_io_entries)); + stats.disk_io_stats = sg_get_disk_io_stats_diff(&(stats.disk_io_entries)); + stats.fs_stats = sg_get_fs_stats(&(stats.fs_entries)); + stats.host_info = sg_get_host_info(); + stats.user_stats = sg_get_user_stats(); - return 1; + return 1; } +void version_num(char *progname){ + fprintf(stderr, "%s version %s\n", progname, PACKAGE_VERSION); + fprintf(stderr, "\nReport bugs to <%s>.\n", PACKAGE_BUGREPORT); + exit(1); +} + +void usage(char *progname){ +#ifdef COLOR_SUPPORT + fprintf(stderr, "Usage: %s [-d delay] [-c] [-v] [-h]\n\n", progname); +#else + fprintf(stderr, "Usage: %s [-d delay] [-v] [-h]\n\n", progname); +#endif + fprintf(stderr, " -d Sets the update time in seconds\n"); +#ifdef COLOR_SUPPORT + fprintf(stderr, " -c Enables coloured output\n"); +#endif + fprintf(stderr, " -v Prints version number\n"); + fprintf(stderr, " -h Displays this help information.\n"); + fprintf(stderr, "\nReport bugs to <%s>.\n", PACKAGE_BUGREPORT); + exit(1); +} + int main(int argc, char **argv){ + extern char *optarg; + int c; + int colouron = 0; - extern char *optarg; - extern int optind; - int c; + time_t last_update = 0; WINDOW *window; - int stdin_fileno; - fd_set infds; - struct timeval timeout; - extern int errno; - char ch; int delay=2; - while ((c = getopt(argc, argv, "d:")) != EOF){ - switch (c){ - case 'd': - delay = atoi(optarg); - if (delay == 0){ + sg_init(); + if(sg_drop_privileges() != 0){ + fprintf(stderr, "Failed to drop setuid/setgid privileges\n"); + return 1; + } + +#ifdef COLOR_SUPPORT + while ((c = getopt(argc, argv, "d:cvh")) != -1){ +#else + while ((c = getopt(argc, argv, "d:vh")) != -1){ +#endif + switch (c){ + case 'd': + delay = atoi(optarg); + if (delay < 1){ fprintf(stderr, "Time must be 1 second or greater\n"); exit(1); } - delay--; - break; - } - } + break; +#ifdef COLOR_SUPPORT + case 'c': + colouron = 1; + break; +#endif + case 'v': + version_num(argv[0]); + break; + case 'h': + default: + usage(argv[0]); + return 1; + break; + } + } signal(SIGWINCH, sig_winch_handler); - initscr(); - nonl(); - cbreak(); - noecho(); - window=newwin(0, 0, 0, 0); + initscr(); +#ifdef COLOR_SUPPORT + /* turn on colour */ + if (colouron) { + if (has_colors()) { + start_color(); + use_default_colors(); + init_pair(1,COLOR_RED,-1); + init_pair(2,COLOR_GREEN,-1); + init_pair(3,COLOR_YELLOW,-1); + init_pair(4,COLOR_BLUE,-1); + init_pair(5,COLOR_MAGENTA,-1); + init_pair(6,COLOR_CYAN,-1); + } else { + fprintf(stderr, "Colour support disabled: your terminal does not support colour."); + colouron = 0; + } + } +#endif + nonl(); + curs_set(0); + cbreak(); + noecho(); + timeout(delay * 1000); + window=newwin(0, 0, 0, 0); clear(); if(!get_stats()){ @@ -368,43 +659,33 @@ int main(int argc, char **argv){ } display_headings(); - stdin_fileno=fileno(stdin); for(;;){ + time_t now; + int ch = getch(); - FD_ZERO(&infds); - FD_SET(stdin_fileno, &infds); - timeout.tv_sec = delay; - timeout.tv_usec = 0; - - if((select((stdin_fileno+1), &infds, NULL, NULL, &timeout)) == -1){ - if(errno!=EINTR){ - perror("select failed"); - exit(1); - } + if (ch == 'q'){ + break; } - if(FD_ISSET(stdin_fileno, &infds)){ - ch=getch(); - if (ch == 'q'){ - endwin(); - return 0; - } + /* To keep the numbers slightly accurate we do not want them + * updating more frequently than once a second. + */ + now = time(NULL); + if ((now - last_update) >= 1) { + get_stats(); } + last_update = now; - get_stats(); + if(sig_winch_flag) { + clear(); + display_headings(); + sig_winch_flag = 0; + } - display_data(); + display_data(colouron); + } - /* To keep the numbers slightly accurate we do not want them updating more - * frequently than once a second. - */ - sleep(1); - - } - - - endwin(); return 0; -} +}