1
0
mirror of https://github.com/Llewellynvdm/conky.git synced 2024-12-26 04:17:33 +00:00

Merge branch 'master' of git.omp.am:/home/omp/git/conky

This commit is contained in:
Brenden Matthews 2009-12-17 18:52:05 -08:00
commit 51ff65ede0
25 changed files with 638 additions and 891 deletions

View File

@ -6,9 +6,13 @@ if(NOT CMAKE_BUILD_TYPE)
FORCE)
endif(NOT CMAKE_BUILD_TYPE)
# -std options for all build types
set(CMAKE_C_FLAGS "-std=c99" CACHE STRING "Flags used by the C compiler during all build types." FORCE)
set(CMAKE_CXX_FLAGS "-std=c++0x" CACHE STRING "Flags used by the C++ compiler during all build types." FORCE)
# some extra debug flags
set(CMAKE_C_FLAGS_DEBUG "-ggdb -Wall -W -Wextra -Wunused -Wdeclaration-after-statement -Wundef -Wendif-labels -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-qual -Wcast-align -Wwrite-strings -Wstrict-prototypes -Wold-style-definition -Winline -Wmissing-noreturn -Wmissing-format-attribute -Wredundant-decls -std=c99 -pedantic -Werror" CACHE STRING "Flags used by the compiler during debug builds." FORCE)
set(CMAKE_CXX_FLAGS_DEBUG "-ggdb -Wall -W -Wextra -Wunused -std=c++0x -pedantic -Werror" CACHE STRING "Flags used by the compiler during debug builds." FORCE)
set(CMAKE_C_FLAGS_DEBUG "-ggdb -Wall -W -Wextra -Wunused -Wdeclaration-after-statement -Wundef -Wendif-labels -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-qual -Wcast-align -Wwrite-strings -Wstrict-prototypes -Wold-style-definition -Winline -Wmissing-noreturn -Wmissing-format-attribute -Wredundant-decls -pedantic -Werror" CACHE STRING "Flags used by the compiler during debug builds." FORCE)
set(CMAKE_CXX_FLAGS_DEBUG "-ggdb -Wall -W -Wextra -Wunused -pedantic -Werror" CACHE STRING "Flags used by the compiler during debug builds." FORCE)
if(CMAKE_BUILD_TYPE MATCHES "Debug")

View File

@ -947,7 +947,7 @@ conky_CXXFLAGS=${conky_CXXFLAGS/-Wdeclaration-after-statement/}
conky_CXXFLAGS=${conky_CXXFLAGS/-Wbad-function-cast/}
conky_CXXFLAGS=${conky_CXXFLAGS/-Wstrict-prototypes/}
conky_CXXFLAGS=${conky_CXXFLAGS/-Wold-style-definition/}
conky_CXXFLAGS=${conky_CXXFLAGS/-std=c99/-std=c++98}
conky_CXXFLAGS=${conky_CXXFLAGS/-std=c99/-std=c++0x}
AC_SUBST(conky_CFLAGS)
AC_SUBST(conky_CXXFLAGS)

View File

@ -810,7 +810,7 @@
<varlistentry>
<term>
<command>
<option>time_in_seconds</option>
<option>times_in_seconds</option>
</command>
</term>
<listitem>If true, variables that output times output a number

View File

@ -5,7 +5,7 @@
syntax "conky" "(\.*conkyrc.*$|conky.conf)"
## Configuration items
color green "\<(alignment|append_file|background|border_inner_margin|border_outer_margin|border_width|color0|color1|color2|color3|color4|color5|color6|color7|color8|color9|colorN|cpu_avg_samples|default_bar_size|default_color|default_gauge_size|default_graph_size|default_outline_color|default_shade_color|diskio_avg_samples|display|double_buffer|draw_borders|draw_graph_borders|draw_outline|draw_shades|extra_newline|font|format_human_readable|gap_x|gap_y|if_up_strictness|imap|imlib_cache_flush_interval|imlib_cache_size|lua_draw_hook_post|lua_draw_hook_pre|lua_load|lua_shutdown_hook|lua_startup_hook|mail_spool|max_port_monitor_connections|max_specials|max_text_width|max_user_text|maximum_width|minimum_size|mpd_host|mpd_password|mpd_port|music_player_interval|net_avg_samples|no_buffers|out_to_console|out_to_ncurses|out_to_stderr|out_to_x|override_utf8_locale|overwrite_file|own_window|own_window_class|own_window_colour|own_window_hints|own_window_title|own_window_transparent|own_window_type|pad_percents|pop3|sensor_device|short_units|show_graph_range|show_graph_scale|stippled_borders|temperature_unit|template|template0|template1|template2|template3|template4|template5|template6|template7|template8|template9|text|text_buffer_size|top_cpu_separate|top_name_width|total_run_times|update_interval|update_interval_on_battery|uppercase|use_spacer|use_xft|xftalpha|xftfont)\>"
color green "\<(alignment|append_file|background|border_inner_margin|border_outer_margin|border_width|color0|color1|color2|color3|color4|color5|color6|color7|color8|color9|colorN|cpu_avg_samples|default_bar_size|default_color|default_gauge_size|default_graph_size|default_outline_color|default_shade_color|diskio_avg_samples|display|double_buffer|draw_borders|draw_graph_borders|draw_outline|draw_shades|extra_newline|font|format_human_readable|gap_x|gap_y|if_up_strictness|imap|imlib_cache_flush_interval|imlib_cache_size|lua_draw_hook_post|lua_draw_hook_pre|lua_load|lua_shutdown_hook|lua_startup_hook|mail_spool|max_port_monitor_connections|max_specials|max_text_width|max_user_text|maximum_width|minimum_size|mpd_host|mpd_password|mpd_port|music_player_interval|net_avg_samples|no_buffers|out_to_console|out_to_ncurses|out_to_stderr|out_to_x|override_utf8_locale|overwrite_file|own_window|own_window_class|own_window_colour|own_window_hints|own_window_title|own_window_transparent|own_window_type|pad_percents|pop3|sensor_device|short_units|show_graph_range|show_graph_scale|stippled_borders|temperature_unit|template|template0|template1|template2|template3|template4|template5|template6|template7|template8|template9|text|text_buffer_size|times_in_seconds|top_cpu_separate|top_name_width|total_run_times|update_interval|update_interval_on_battery|uppercase|use_spacer|use_xft|xftalpha|xftfont)\>"
## Configuration item constants
color yellow "\<(above|below|bottom_left|bottom_right|bottom_middle|desktop|dock|no|none|normal|override|skip_pager|skip_taskbar|sticky|top_left|top_right|top_middle|middle_left|middle_right|middle_middle|undecorated|yes)\>"

View File

@ -12,7 +12,7 @@ endif
syn region ConkyrcComment start=/^\s*#/ end=/$/
syn keyword ConkyrcSetting alignment append_file background border_inner_margin border_outer_margin border_width color0 color1 color2 color3 color4 color5 color6 color7 color8 color9 colorN cpu_avg_samples default_bar_size default_color default_gauge_size default_graph_size default_outline_color default_shade_color diskio_avg_samples display double_buffer draw_borders draw_graph_borders draw_outline draw_shades extra_newline font format_human_readable gap_x gap_y if_up_strictness imap imlib_cache_flush_interval imlib_cache_size lua_draw_hook_post lua_draw_hook_pre lua_load lua_shutdown_hook lua_startup_hook mail_spool max_port_monitor_connections max_specials max_text_width max_user_text maximum_width minimum_size mpd_host mpd_password mpd_port music_player_interval net_avg_samples no_buffers out_to_console out_to_ncurses out_to_stderr out_to_x override_utf8_locale overwrite_file own_window own_window_class own_window_colour own_window_hints own_window_title own_window_transparent own_window_type pad_percents pop3 sensor_device short_units show_graph_range show_graph_scale stippled_borders temperature_unit template template0 template1 template2 template3 template4 template5 template6 template7 template8 template9 text text_buffer_size top_cpu_separate top_name_width total_run_times update_interval update_interval_on_battery uppercase use_spacer use_xft xftalpha xftfont
syn keyword ConkyrcSetting alignment append_file background border_inner_margin border_outer_margin border_width color0 color1 color2 color3 color4 color5 color6 color7 color8 color9 colorN cpu_avg_samples default_bar_size default_color default_gauge_size default_graph_size default_outline_color default_shade_color diskio_avg_samples display double_buffer draw_borders draw_graph_borders draw_outline draw_shades extra_newline font format_human_readable gap_x gap_y if_up_strictness imap imlib_cache_flush_interval imlib_cache_size lua_draw_hook_post lua_draw_hook_pre lua_load lua_shutdown_hook lua_startup_hook mail_spool max_port_monitor_connections max_specials max_text_width max_user_text maximum_width minimum_size mpd_host mpd_password mpd_port music_player_interval net_avg_samples no_buffers out_to_console out_to_ncurses out_to_stderr out_to_x override_utf8_locale overwrite_file own_window own_window_class own_window_colour own_window_hints own_window_title own_window_transparent own_window_type pad_percents pop3 sensor_device short_units show_graph_range show_graph_scale stippled_borders temperature_unit template template0 template1 template2 template3 template4 template5 template6 template7 template8 template9 text text_buffer_size times_in_seconds top_cpu_separate top_name_width total_run_times update_interval update_interval_on_battery uppercase use_spacer use_xft xftalpha xftfont
syn keyword ConkyrcConstant
\ above

View File

@ -53,8 +53,8 @@ mandatory_sources = colours.c colours.h combine.c combine.h common.c common.h \
conky.cc conky.h core.cc core.h diskio.c diskio.h entropy.c entropy.h \
exec.c exec.h fs.c fs.h logging.h mail.c mail.h mixer.c mixer.h net_stat.c \
net_stat.h template.c template.h timed_thread.c timed_thread.h mboxscan.c \
mboxscan.h read_tcp.c read_tcp.h scroll.c scroll.h specials.c \
specials.h tailhead.c tailhead.h temphelper.c temphelper.h \
mboxscan.h prioqueue.c prioqueue.h read_tcp.c read_tcp.h scroll.c scroll.h \
specials.c specials.h tailhead.c tailhead.h temphelper.c temphelper.h \
text_object.c text_object.h timeinfo.c timeinfo.h top.c top.h algebra.c \
algebra.h proc.c proc.h user.c user.h

View File

@ -40,13 +40,13 @@ enum match_type {
OP_EQ = 3, /* == */
OP_LEQ = 4, /* <= */
OP_GEQ = 5, /* >= */
OP_NEQ = 6, /* != */
OP_NEQ = 6 /* != */
};
enum arg_type {
ARG_STRING = 1, /* "asdf" */
ARG_LONG = 2, /* 123456 */
ARG_DOUBLE = 3, /* 12.456 */
ARG_DOUBLE = 3 /* 12.456 */
};
int compare(const char *);

View File

@ -33,12 +33,37 @@
#include <sys/time.h>
#include <unistd.h>
enum _apcupsd_items {
APCUPSD_NAME,
APCUPSD_MODEL,
APCUPSD_UPSMODE,
APCUPSD_CABLE,
APCUPSD_STATUS,
APCUPSD_LINEV,
APCUPSD_LOAD,
APCUPSD_CHARGE,
APCUPSD_TIMELEFT,
APCUPSD_TEMP,
APCUPSD_LASTXFER,
_APCUPSD_COUNT
};
/* type for data exchange with main thread */
#define APCUPSD_MAXSTR 32
typedef struct apcupsd_s {
char items[_APCUPSD_COUNT][APCUPSD_MAXSTR+1]; /* e.g. items[APCUPSD_STATUS] */
char host[64];
int port;
} APCUPSD_S, *PAPCUPSD_S;
static APCUPSD_S apcupsd;
//
// encapsulated recv()
//
static int net_recv_ex(int sock, void *buf, int size, struct timeval *tv)
{
fd_set fds;
int res;
@ -74,8 +99,8 @@ static int net_recv_ex(int sock, void *buf, int size, struct timeval *tv)
//
// read whole buffer or fail
//
static int net_recv(int sock, void* buf, int size) {
static int net_recv(int sock, void* buf, int size)
{
int todo = size;
int off = 0;
int len;
@ -93,8 +118,8 @@ static int net_recv(int sock, void* buf, int size) {
//
// get one response line
//
static int get_line(int sock, char line[], short linesize) {
static int get_line(int sock, char line[], short linesize)
{
// get the line length
short sz;
if (!net_recv(sock, &sz, sizeof(sz))) return -1;
@ -130,8 +155,8 @@ static int get_line(int sock, char line[], short linesize) {
//
// fills in the data received from a socket
//
static int fill_items(int sock, PAPCUPSD_S apc) {
static int fill_items(int sock, PAPCUPSD_S apc)
{
char line[512];
int len;
while ((len = get_line(sock, line, sizeof(line)))) {
@ -148,15 +173,15 @@ static int fill_items(int sock, PAPCUPSD_S apc) {
FILL("ITEMP", APCUPSD_TEMP, TRUE);
FILL("LASTXFER", APCUPSD_LASTXFER, FALSE);
}
return len == 0;
}
//
// Conky update function for apcupsd data
//
void update_apcupsd(void) {
void update_apcupsd(void)
{
int i;
APCUPSD_S apc;
int sock;
@ -182,27 +207,27 @@ void update_apcupsd(void) {
break;
}
#ifdef HAVE_GETHOSTBYNAME_R
if (gethostbyname_r(info.apcupsd.host, &he_mem, hostbuff, sizeof(hostbuff), &he, &he_errno) || !he ) {
if (gethostbyname_r(apcupsd.host, &he_mem, hostbuff, sizeof(hostbuff), &he, &he_errno) || !he ) {
NORM_ERR("APCUPSD gethostbyname_r: %s", hstrerror(h_errno));
break;
}
#else /* HAVE_GETHOSTBYNAME_R */
he = gethostbyname(info.apcupsd.host);
he = gethostbyname(apcupsd.host);
if (!he) {
herror("gethostbyname");
break;
}
#endif /* HAVE_GETHOSTBYNAME_R */
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = info.apcupsd.port;
addr.sin_port = apcupsd.port;
memcpy(&addr.sin_addr, he->h_addr, he->h_length);
if (connect(sock, (struct sockaddr*)&addr, sizeof(struct sockaddr)) < 0) {
// no error reporting, the daemon is probably not running
break;
}
//
// send status request - "status" - 6B
//
@ -212,7 +237,7 @@ void update_apcupsd(void) {
perror("send");
break;
}
//
// read the lines of output and put them into the info structure
//
@ -225,22 +250,34 @@ void update_apcupsd(void) {
//
// "atomically" copy the data into working set
//
memcpy(info.apcupsd.items, apc.items, sizeof(info.apcupsd.items));
memcpy(apcupsd.items, apc.items, sizeof(apcupsd.items));
return;
}
int apcupsd_scan_arg(const char *arg)
{
char host[64];
int port;
if (sscanf(arg, "%63s %d", host, &port) != 2)
return 1;
apcupsd.port = htons(port);
strncpy(apcupsd.host, host, sizeof(apcupsd.host));
return 0;
}
double apcupsd_loadbarval(struct text_object *obj)
{
(void)obj;
return atof(info.apcupsd.items[APCUPSD_LOAD]);
return atof(apcupsd.items[APCUPSD_LOAD]);
}
#define APCUPSD_PRINT_GENERATOR(name, idx) \
void print_apcupsd_##name(struct text_object *obj, char *p, int p_max_size) \
{ \
(void)obj; \
snprintf(p, p_max_size, "%s", info.apcupsd.items[APCUPSD_##idx]); \
snprintf(p, p_max_size, "%s", apcupsd.items[APCUPSD_##idx]); \
}
APCUPSD_PRINT_GENERATOR(name, NAME)

View File

@ -29,28 +29,7 @@
extern "C" {
#endif
enum _apcupsd_items {
APCUPSD_NAME,
APCUPSD_MODEL,
APCUPSD_UPSMODE,
APCUPSD_CABLE,
APCUPSD_STATUS,
APCUPSD_LINEV,
APCUPSD_LOAD,
APCUPSD_CHARGE,
APCUPSD_TIMELEFT,
APCUPSD_TEMP,
APCUPSD_LASTXFER,
_APCUPSD_COUNT,
};
/* type for data exchange with main thread */
#define APCUPSD_MAXSTR 32
typedef struct apcupsd_s {
char items[_APCUPSD_COUNT][APCUPSD_MAXSTR+1]; /* e.g. items[APCUPSD_STATUS] */
char host[64];
int port;
} APCUPSD_S, *PAPCUPSD_S;
int apcupsd_scan_arg(const char *);
/* Service routine for the conky main thread */
void update_apcupsd(void);

View File

@ -33,6 +33,7 @@
#include "conky.h"
#include "common.h"
#include "timed_thread.h"
#include <ctype.h>
#include <stdarg.h>
#include <math.h>
#include <time.h>
@ -73,35 +74,21 @@
/* local headers */
#include "core.h"
#include "algebra.h"
#include "build.h"
#include "colours.h"
#include "combine.h"
#include "diskio.h"
#include "exec.h"
#include "proc.h"
#include "user.h"
#ifdef X11
#include "fonts.h"
#endif
#include "fs.h"
#ifdef HAVE_ICONV
#include "iconv_tools.h"
#endif
#include "logging.h"
#include "mixer.h"
#include "mail.h"
#include "mboxscan.h"
#include "net_stat.h"
#ifdef NVIDIA
#include "nvidia.h"
#endif
#include "read_tcp.h"
#include "scroll.h"
#include "specials.h"
#include "temphelper.h"
#include "template.h"
#include "tailhead.h"
#include "timeinfo.h"
#include "top.h"
@ -143,7 +130,7 @@ static char *tmpstring1, *tmpstring2;
int short_units;
int format_human_readable;
int cpu_separate;
enum {
enum spacer_state {
NO_SPACER = 0,
LEFT_SPACER,
RIGHT_SPACER
@ -734,8 +721,10 @@ void generate_text_internal(char *p, int p_max_size, struct text_object root)
struct text_object *obj;
size_t a;
#ifdef HAVE_ICONV
char buff_in[p_max_size];
buff_in[0] = 0;
char *buff_in;
buff_in = (char *)malloc(p_max_size);
memset(buff_in, 0, p_max_size);
#endif /* HAVE_ICONV */
p[0] = 0;
@ -779,6 +768,9 @@ void generate_text_internal(char *p, int p_max_size, struct text_object root)
/* load any new fonts we may have had */
load_fonts();
#endif /* X11 */
#ifdef HAVE_ICONV
free(buff_in);
#endif /* HAVE_ICONV */
}
void evaluate(const char *text, char *p, int p_max_size)
@ -1216,7 +1208,7 @@ static void draw_string(const char *s)
int draw_each_line_inner(char *s, int special_index, int last_special_applied)
{
#ifdef X11
int font_h;
int font_h = 0;
int cur_y_add = 0;
#endif /* X11 */
char *recurse = 0;
@ -1484,32 +1476,29 @@ int draw_each_line_inner(char *s, int special_index, int last_special_applied)
unsigned short int timeunits;
if (seconds != 0) {
timeunits = seconds / 86400; seconds %= 86400;
if (timeunits > 0) {
asprintf(&tmp_day_str, "%dd", timeunits);
} else {
if (timeunits <= 0 ||
asprintf(&tmp_day_str, "%dd", timeunits) == -1) {
tmp_day_str = strdup("");
}
timeunits = seconds / 3600; seconds %= 3600;
if (timeunits > 0) {
asprintf(&tmp_hour_str, "%dh", timeunits);
} else {
if (timeunits <= 0 ||
asprintf(&tmp_hour_str, "%dh", timeunits) == -1) {
tmp_hour_str = strdup("");
}
timeunits = seconds / 60; seconds %= 60;
if (timeunits > 0) {
asprintf(&tmp_min_str, "%dm", timeunits);
} else {
if (timeunits <= 0 ||
asprintf(&tmp_min_str, "%dm", timeunits) == -1) {
tmp_min_str = strdup("");
}
if (seconds > 0) {
asprintf(&tmp_sec_str, "%ds", seconds);
} else {
if (seconds <= 0 ||
asprintf(&tmp_sec_str, "%ds", seconds) == -1) {
tmp_sec_str = strdup("");
}
asprintf(&tmp_str, "%s%s%s%s", tmp_day_str, tmp_hour_str, tmp_min_str, tmp_sec_str);
if (asprintf(&tmp_str, "%s%s%s%s", tmp_day_str, tmp_hour_str, tmp_min_str, tmp_sec_str) == -1)
tmp_str = strdup("");
free(tmp_day_str); free(tmp_hour_str); free(tmp_min_str); free(tmp_sec_str);
} else {
asprintf(&tmp_str, "Range not possible"); // should never happen, but better safe then sorry
tmp_str = strdup("Range not possible"); // should never happen, but better safe then sorry
}
cur_x += (w / 2) - (font_ascent() * (strlen(tmp_str) / 2));
cur_y += font_h / 2;
@ -1876,9 +1865,9 @@ static void main_loop(void)
info.looped = 0;
while (terminate == 0 && (total_run_times == 0 || info.looped < total_run_times)) {
if(update_interval_bat != NOBATTERY && update_interval_bat != update_interval_old) {
char buf[max_user_text];
char buf[64];
get_battery_short_status(buf, max_user_text, "BAT0");
get_battery_short_status(buf, 64, "BAT0");
if(buf[0] == 'D') {
update_interval = update_interval_bat;
} else {
@ -2583,7 +2572,7 @@ static void set_default_configurations(void)
mpd_set_host(mpd_env_host);
} else {
/* MPD_HOST contains a password */
char mpd_password[mpd_hostpart - mpd_env_host + 1];
char *mpd_password = (char *)malloc(mpd_hostpart - mpd_env_host + 1);
snprintf(mpd_password, mpd_hostpart - mpd_env_host + 1, "%s", mpd_env_host);
if (!strlen(mpd_hostpart + 1)) {
@ -2593,6 +2582,7 @@ static void set_default_configurations(void)
}
mpd_set_password(mpd_password, 1);
free(mpd_password);
}
}
@ -4186,7 +4176,8 @@ int main(int argc, char **argv)
current_config = strndup(optarg, max_user_text);
break;
case 'q':
freopen("/dev/null", "w", stderr);
if (freopen("/dev/null", "w", stderr))
CRIT_ERR(0, 0, "could not open /dev/null as stderr!");
break;
case 'h':
print_help(argv[0]);

View File

@ -116,11 +116,6 @@ struct text_object;
#include "xmms2.h"
#endif
#ifdef IBM
#include "ibm.h"
#include "smapi.h"
#endif
#ifdef APCUPSD
#include "apcupsd.h"
#endif
@ -247,10 +242,6 @@ struct information {
struct x11_info x11;
#endif
#ifdef APCUPSD
APCUPSD_S apcupsd;
#endif
short kflags; /* kernel settings, see enum KFLAG */
};

View File

@ -46,6 +46,10 @@
#include "fonts.h"
#endif
#include "fs.h"
#ifdef IBM
#include "ibm.h"
#include "smapi.h"
#endif
#ifdef HAVE_ICONV
#include "iconv_tools.h"
#endif
@ -139,7 +143,7 @@ struct text_object *construct_text_object(const char *s, const char *arg, long
/* helper defines for internal use only */
#define __OBJ_HEAD(a, n) if (!strcmp(s, #a)) { \
obj->type = OBJ_##a; add_update_callback(n);
add_update_callback(n);
#define __OBJ_IF obj_be_ifblock_if(ifblock_opaque, obj)
#define __OBJ_ARG(...) if (!arg) { CRIT_ERR(obj, free_at_crash, __VA_ARGS__); }
@ -152,23 +156,19 @@ struct text_object *construct_text_object(const char *s, const char *arg, long
#ifdef X11
if (s[0] == '#') {
obj->type = OBJ_color;
obj->data.l = get_x11_color(s);
obj->callbacks.print = &new_fg;
} else
#endif /* X11 */
#ifdef __OpenBSD__
OBJ(freq, 0)
obj->callbacks.print = &print_freq;
#else
#ifndef __OpenBSD__
OBJ(acpitemp, 0)
obj->data.i = open_acpi_temperature(arg);
obj->callbacks.print = &print_acpitemp;
obj->callbacks.free = &free_acpitemp;
END OBJ(acpiacadapter, 0)
obj->callbacks.print = &print_acpiacadapter;
END OBJ(freq, 0)
#endif /* !__OpenBSD__ */
END OBJ(freq, 0)
get_cpu_count();
if (!arg || !isdigit(arg[0]) || strlen(arg) >= 2 || atoi(&arg[0]) == 0
|| atoi(&arg[0]) > info.cpu_count) {
@ -678,13 +678,12 @@ struct text_object *construct_text_object(const char *s, const char *arg, long
/* XXX: maybe fiddle them apart later, as print_top() does
* nothing else than just that, using an ugly switch(). */
if (strncmp(s, "top", 3) == EQUAL) {
add_update_callback(&update_meminfo);
add_update_callback(&update_top);
if (!parse_top_args(s, arg, obj)) {
if (parse_top_args(s, arg, obj)) {
add_update_callback(&update_top);
} else {
free(obj);
return NULL;
}
obj->callbacks.print = &print_top;
obj->callbacks.free = &free_top;
} else
#ifdef __linux__
OBJ(addr, &update_net_stats)
@ -1547,13 +1546,8 @@ struct text_object *construct_text_object(const char *s, const char *arg, long
#endif /* NVIDIA */
#ifdef APCUPSD
END OBJ_ARG(apcupsd, &update_apcupsd, "apcupsd needs arguments: <host> <port>")
char host[64];
int port;
if (sscanf(arg, "%63s %d", host, &port) != 2) {
if (apcupsd_scan_arg(arg)) {
CRIT_ERR(obj, free_at_crash, "apcupsd needs arguments: <host> <port>");
} else {
info.apcupsd.port = htons(port);
strncpy(info.apcupsd.host, host, sizeof(info.apcupsd.host));
}
obj->callbacks.print = &gen_print_nothing;
END OBJ(apcupsd_name, &update_apcupsd)
@ -1593,11 +1587,12 @@ struct text_object *construct_text_object(const char *s, const char *arg, long
obj->callbacks.print = &print_apcupsd_lastxfer;
#endif /* APCUPSD */
END {
char buf[text_buffer_size];
char *buf = (char *)malloc(text_buffer_size);
NORM_ERR("unknown variable %s", s);
snprintf(buf, text_buffer_size, "${%s}", s);
obj_be_plain_text(obj, buf);
free(buf);
}
#undef OBJ
#undef OBJ_IF
@ -1690,7 +1685,7 @@ int extract_variable_text_internal(struct text_object *retval, const char *const
s = p;
if (*p != '$') {
char buf[text_buffer_size];
char *buf = (char *)malloc(text_buffer_size);
const char *var;
/* variable is either $foo or ${foo} */
@ -1737,6 +1732,7 @@ int extract_variable_text_internal(struct text_object *retval, const char *const
if (obj) {
append_object(retval, obj);
}
free(buf);
continue;
}
@ -1769,6 +1765,7 @@ int extract_variable_text_internal(struct text_object *retval, const char *const
if (obj != NULL) {
append_object(retval, obj);
}
free(buf);
continue;
} else {
obj = create_plain_text("$");

View File

@ -3,8 +3,6 @@
#ifndef _IBM_H
#define _IBM_H
#include <sys/types.h>
#ifdef __cplusplus
extern "C" {
#endif

View File

@ -63,6 +63,7 @@
#endif
#include <linux/route.h>
#include <math.h>
#include <pthread.h>
/* The following ifdefs were adapted from gkrellm */
#include <linux/major.h>
@ -688,14 +689,20 @@ void update_stat(void)
const char *stat_template = NULL;
unsigned int malloc_cpu_size = 0;
extern void* global_cpu;
static pthread_mutex_t last_stat_update_mutex = PTHREAD_MUTEX_INITIALIZER;
static double last_stat_update = 0.0;
/* since we use wrappers for this function, the update machinery
* can't eliminate double invocations of this function. Check for
* them here, otherwise cpu_usage counters are freaking out. */
if (last_stat_update == current_update_time)
pthread_mutex_lock(&last_stat_update_mutex);
if (last_stat_update == current_update_time) {
pthread_mutex_unlock(&last_stat_update_mutex);
return;
}
last_stat_update = current_update_time;
pthread_mutex_unlock(&last_stat_update_mutex);
/* add check for !info.cpu_usage since that mem is freed on a SIGUSR1 */
if (!cpu_setup || !info.cpu_usage) {

View File

@ -653,9 +653,7 @@ static void *imap_thread(void *arg)
unsigned long old_unseen = ULONG_MAX;
unsigned long old_messages = ULONG_MAX;
struct stat stat_buf;
struct hostent he, *he_res = 0;
int he_errno;
char hostbuff[2048];
struct hostent *he_res = 0;
struct sockaddr_in their_addr; // connector's address information
struct mail_s *mail = (struct mail_s *)arg;
int has_idle = 0;
@ -669,6 +667,10 @@ static void *imap_thread(void *arg)
if (!resolved_host) {
#ifdef HAVE_GETHOSTBYNAME_R
int he_errno;
struct hostent he;
char hostbuff[2048];
if (gethostbyname_r(mail->host, &he, hostbuff, sizeof(hostbuff), &he_res, &he_errno)) { // get the host info
NORM_ERR("IMAP gethostbyname_r: %s", hstrerror(h_errno));
fail++;
@ -1008,9 +1010,7 @@ static void *pop3_thread(void *arg)
unsigned int fail = 0;
unsigned long old_unseen = ULONG_MAX;
struct stat stat_buf;
struct hostent he, *he_res = 0;
int he_errno;
char hostbuff[2048];
struct hostent *he_res = 0;
struct sockaddr_in their_addr; // connector's address information
struct mail_s *mail = (struct mail_s *)arg;
char resolved_host = 0;
@ -1021,6 +1021,10 @@ static void *pop3_thread(void *arg)
fd_set fdset;
if (!resolved_host) {
#ifdef HAVE_GETHOSTBYNAME_R
int he_errno;
struct hostent he;
char hostbuff[2048];
if (gethostbyname_r(mail->host, &he, hostbuff, sizeof(hostbuff), &he_res, &he_errno)) { // get the host info
NORM_ERR("POP3 gethostbyname_r: %s", hstrerror(h_errno));
fail++;

207
src/prioqueue.c Normal file
View File

@ -0,0 +1,207 @@
/* -*- mode: c; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=c
*
* prioqueue: a simple priority queue implementation
*
* The queue organises it's data internally using a doubly linked
* list, into which elements are inserted at the right position. This
* is definitely not the best algorithm for a priority queue, but it
* fits best for the given purpose, i.e. the top process sorting.
* This means we have a rather little amount of total elements (~200
* on a normal system), which are to be inserted into a queue of only
* the few top-most elements (10 at the current state). Additionally,
* at each update interval, the queue is drained completely and
* refilled from scratch.
*
* Copyright (C) 2009 Phil Sutter <phil@nwl.cc>
*
* Initially based on the former implementation of sorted processes in
* top.c, Copyright (C) 2005 David Carter <boojit@pundo.com>
*
* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include <limits.h> /* INT_MAX */
#include <stdlib.h>
#include <string.h>
struct prio_elem {
struct prio_elem *next, *prev;
void *data;
};
struct prio_queue {
/* Compare a and b. Return:
* <0 if a should come before b,
* >0 if b should come before a,
* 0 if don't care */
int (*compare)(void *a, void *b);
/* Free element payload. Called when dropping elements. */
void (*free)(void *a);
/* Maximum size of queue. The first
* elements in the list take precedence. */
int max_size;
/* The pointers to the actual list. */
struct prio_elem *head, *tail;
/* The current number of elements in the list. */
int cur_size;
};
/* nop callback to save us from conditional calling */
static void pq_free_nop(void *a) { (void)a; }
struct prio_queue *init_prio_queue(void)
{
struct prio_queue *retval;
retval = malloc(sizeof(struct prio_queue));
memset(retval, 0, sizeof(struct prio_queue));
/* use pq_free_nop by default */
retval->free = &pq_free_nop;
/* Default to maximum possible size as restricted
* by the used data type. This also saves us from
* checking if caller has set this field or not. */
retval->max_size = INT_MAX;
return retval;
}
void pq_set_compare(struct prio_queue *queue, int (*pqcompare)(void *a, void *b))
{
if (pqcompare)
queue->compare = pqcompare;
}
void pq_set_free(struct prio_queue *queue, void (*pqfree)(void *a))
{
if (pqfree)
queue->free = pqfree;
}
void pq_set_max_size(struct prio_queue *queue, int max_size)
{
if (max_size >= 0)
queue->max_size = max_size;
}
int pq_get_cur_size(struct prio_queue *queue)
{
return queue->cur_size;
}
static struct prio_elem *init_prio_elem(void *data)
{
struct prio_elem *retval;
retval = malloc(sizeof(struct prio_elem));
memset(retval, 0, sizeof(struct prio_elem));
retval->data = data;
return retval;
}
void insert_prio_elem(struct prio_queue *queue, void *data)
{
struct prio_elem *cur;
/* queue->compare is a must-have */
if (!queue->compare)
return;
/* empty queue, insert the first item */
if (!queue->cur_size) {
queue->cur_size++;
queue->head = queue->tail = init_prio_elem(data);
return;
}
/* short-cut 1: new item is lower than all others */
if (queue->compare(queue->tail->data, data) <= 0) {
if (queue->cur_size < queue->max_size) {
queue->cur_size++;
queue->tail->next = init_prio_elem(data);
queue->tail->next->prev = queue->tail;
queue->tail = queue->tail->next;
} else /* list was already full */
(*queue->free)(data);
return;
}
/* short-cut 2: we have a new maximum */
if (queue->compare(queue->head->data, data) >= 0) {
queue->cur_size++;
queue->head->prev = init_prio_elem(data);
queue->head->prev->next = queue->head;
queue->head = queue->head->prev;
goto check_cur_size;
}
/* find the actual position if short-cuts failed */
for (cur = queue->head->next; cur; cur = cur->next) {
if (queue->compare(cur->data, data) >= 0) {
queue->cur_size++;
cur->prev->next = init_prio_elem(data);
cur->prev->next->prev = cur->prev;
cur->prev->next->next = cur;
cur->prev = cur->prev->next;
break;
}
}
check_cur_size:
/* drop the lowest item if queue overrun */
if (queue->cur_size > queue->max_size) {
queue->cur_size--;
queue->tail = queue->tail->prev;
(*queue->free)(queue->tail->next->data);
free(queue->tail->next);
queue->tail->next = NULL;
}
}
void *pop_prio_elem(struct prio_queue *queue)
{
struct prio_elem *tmp;
void *data;
if (queue->cur_size <= 0)
return NULL;
tmp = queue->head;
data = tmp->data;
queue->head = queue->head->next;
queue->cur_size--;
if (queue->head)
queue->head->prev = NULL;
else /* list is now empty */
queue->tail = NULL;
free(tmp);
return data;
}
void free_prio_queue(struct prio_queue *queue)
{
void *data;
while((data = pop_prio_elem(queue)))
(*queue->free)(data);
free(queue);
}

66
src/prioqueue.h Normal file
View File

@ -0,0 +1,66 @@
/* -*- mode: c; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
* vim: ts=4 sw=4 noet ai cindent syntax=c
*
* prioqueue: a simple priority queue implementation
*
* Copyright (C) 2009 Phil Sutter <phil@nwl.cc>
*
* Initially based on the former implementation of sorted processes in
* top.c, Copyright (C) 2005 David Carter <boojit@pundo.com>
*
* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef _PRIOQUEUE_H
#define _PRIOQUEUE_H
/* forward-define for private data */
struct prio_queue;
/* typedef for a distinct prioqueue object */
typedef struct prio_queue *prio_queue_t;
/* initialise a prioqueue object (mandatory) */
prio_queue_t init_prio_queue(void);
/* set the compare function (mandatory)
* (*compare) shall return:
* <0 if a should come before b,
* >0 if b should come before a,
* 0 if doesn't matter */
void pq_set_compare(prio_queue_t, int (*compare)(void *a, void *b));
/* set the data free function (optional)
* (*free) will be called when:
* - dropping elements from the end of a limited size queue and
* - free_prio_queue() finds leftover elements in the given queue */
void pq_set_free(prio_queue_t, void (*free)(void *));
/* set a maximum queue size (optional) (defaults to INT_MAX) */
void pq_set_max_size(prio_queue_t, int);
/* insert an element into the given queue */
void insert_prio_elem(prio_queue_t, void *);
/* return the number of elements in the queue */
int pq_get_cur_size(prio_queue_t queue);
/* pop the top-most element from the queue
* returns NULL if queue is empty */
void *pop_prio_elem(prio_queue_t);
/* clear and free the given queue */
void free_prio_queue(prio_queue_t);
#endif /* _PRIOQUEUE_H */

View File

@ -73,8 +73,8 @@ void parse_scroll_arg(struct text_object *obj, const char *arg, void *free_at_cr
#ifdef X11
/* add a color object right after scroll to reset any color changes */
obj->next->type = OBJ_color;
obj->next->data.l = sd->resetcolor;
obj->next->callbacks.print = &new_fg;
#endif /* X11 */
}

View File

@ -22,7 +22,6 @@
*
*/
#include "conky.h" /* text_buffer_size, PACKAGE_NAME, maybe more */
#include "smapi.h"
#include "temphelper.h"
#include "logging.h"
#include <stdio.h>
@ -33,7 +32,18 @@
#define SYS_SMAPI_PATH "/sys/devices/platform/smapi"
int smapi_bat_installed_internal(int idx)
static int smapi_read_int(const char *path)
{
FILE *fp;
int i = 0;
if ((fp = fopen(path, "r")) != NULL) {
fscanf(fp, "%i\n", &i);
fclose(fp);
}
return i;
}
static int smapi_bat_installed_internal(int idx)
{
char path[128];
struct stat sb;
@ -48,7 +58,7 @@ int smapi_bat_installed_internal(int idx)
}
char *smapi_read_str(const char *path)
static char *smapi_read_str(const char *path)
{
FILE *fp;
char str[256] = "failed";
@ -59,18 +69,7 @@ char *smapi_read_str(const char *path)
return strndup(str, text_buffer_size);
}
int smapi_read_int(const char *path)
{
FILE *fp;
int i = 0;
if ((fp = fopen(path, "r")) != NULL) {
fscanf(fp, "%i\n", &i);
fclose(fp);
}
return i;
}
char *smapi_get_str(const char *fname)
static char *smapi_get_str(const char *fname)
{
char path[128];
if(snprintf(path, 127, SYS_SMAPI_PATH "/%s", fname) < 0)
@ -79,7 +78,7 @@ char *smapi_get_str(const char *fname)
return smapi_read_str(path);
}
char *smapi_get_bat_str(int idx, const char *fname)
static char *smapi_get_bat_str(int idx, const char *fname)
{
char path[128];
if(snprintf(path, 127, SYS_SMAPI_PATH "/BAT%i/%s", idx, fname) < 0)
@ -87,7 +86,7 @@ char *smapi_get_bat_str(int idx, const char *fname)
return smapi_read_str(path);
}
int smapi_get_bat_int(int idx, const char *fname)
static int smapi_get_bat_int(int idx, const char *fname)
{
char path[128];
if(snprintf(path, 127, SYS_SMAPI_PATH "/BAT%i/%s", idx, fname) < 0)
@ -95,7 +94,7 @@ int smapi_get_bat_int(int idx, const char *fname)
return smapi_read_int(path);
}
char *smapi_get_bat_val(const char *args)
static char *smapi_get_bat_val(const char *args)
{
char fname[128];
int idx, cnt;
@ -112,7 +111,7 @@ char *smapi_get_bat_val(const char *args)
return smapi_get_bat_str(idx, fname);
}
char *smapi_get_val(const char *args)
static char *smapi_get_val(const char *args)
{
char str[128];

View File

@ -28,18 +28,6 @@
extern "C" {
#endif
int smapi_bat_installed_internal(int);
char *smapi_read_str(const char *);
int smapi_read_int(const char *);
char *smapi_get_str(const char *);
char *smapi_get_val(const char *);
char *smapi_get_bat_str(int, const char *);
int smapi_get_bat_int(int, const char *);
char *smapi_get_bat_val(const char *);
void print_smapi(struct text_object *, char *, int);
uint8_t smapi_bat_percentage(struct text_object *);
void print_smapi_bat_temp(struct text_object *, char *, int);

View File

@ -59,7 +59,7 @@ enum special_types {
VOFFSET,
FONT,
GOTO,
TAB,
TAB
};
struct special_t {

View File

@ -196,7 +196,6 @@ int ifblock_stack_empty(void **opaque)
void obj_be_plain_text(struct text_object *obj, const char *text)
{
obj->type = OBJ_text;
obj->data.s = strdup(text);
obj->verbatim_output = 1;

View File

@ -37,444 +37,6 @@
extern "C" {
#endif
enum text_object_type {
OBJ_read_tcp,
OBJ_addr,
#if defined(__linux__)
OBJ_addrs,
#endif /* __linux__ */
#ifndef __OpenBSD__
OBJ_acpiacadapter,
OBJ_acpifan,
OBJ_acpitemp,
OBJ_battery,
OBJ_battery_time,
OBJ_battery_percent,
OBJ_battery_bar,
OBJ_battery_short,
#endif /* !__OpenBSD__ */
OBJ_buffers,
OBJ_cached,
OBJ_color,
OBJ_color0,
OBJ_color1,
OBJ_color2,
OBJ_color3,
OBJ_color4,
OBJ_color5,
OBJ_color6,
OBJ_color7,
OBJ_color8,
OBJ_color9,
OBJ_conky_version,
OBJ_conky_build_date,
OBJ_conky_build_arch,
OBJ_font,
OBJ_cpu,
OBJ_cpubar,
OBJ_cpugauge,
#ifdef X11
OBJ_cpugraph,
OBJ_loadgraph,
#endif /* X11 */
OBJ_diskio,
OBJ_diskio_read,
OBJ_diskio_write,
#ifdef X11
OBJ_diskiograph,
OBJ_diskiograph_read,
OBJ_diskiograph_write,
#endif /* X11 */
OBJ_downspeed,
OBJ_downspeedf,
#ifdef X11
OBJ_downspeedgraph,
#endif /* X11 */
OBJ_else,
OBJ_endif,
OBJ_eval,
OBJ_image,
OBJ_exec,
OBJ_execi,
OBJ_texeci,
OBJ_execbar,
OBJ_execibar,
OBJ_execgauge,
OBJ_execigauge,
#ifdef X11
OBJ_execgraph,
OBJ_execigraph,
#endif /* X11 */
OBJ_execp,
OBJ_execpi,
OBJ_freq,
OBJ_freq_g,
OBJ_fs_bar,
OBJ_fs_bar_free,
OBJ_fs_free,
OBJ_fs_free_perc,
OBJ_fs_size,
OBJ_fs_type,
OBJ_fs_used,
OBJ_fs_used_perc,
OBJ_goto,
OBJ_tab,
OBJ_hr,
OBJ_offset,
OBJ_voffset,
OBJ_alignr,
OBJ_alignc,
OBJ_i2c,
OBJ_platform,
OBJ_hwmon,
#if defined(__linux__)
OBJ_disk_protect,
OBJ_i8k_version,
OBJ_i8k_bios,
OBJ_i8k_serial,
OBJ_i8k_cpu_temp,
OBJ_i8k_left_fan_status,
OBJ_i8k_right_fan_status,
OBJ_i8k_left_fan_rpm,
OBJ_i8k_right_fan_rpm,
OBJ_i8k_ac_status,
OBJ_i8k_buttons_status,
#if defined(IBM)
OBJ_ibm_fan,
OBJ_ibm_temps,
OBJ_ibm_volume,
OBJ_ibm_brightness,
OBJ_smapi,
#ifdef X11
OBJ_smapi_bat_bar,
#endif /* X11 */
OBJ_smapi_bat_perc,
OBJ_smapi_bat_temp,
OBJ_smapi_bat_power,
OBJ_if_smapi_bat_installed,
#endif /* IBM */
/* information from sony_laptop kernel module
* /sys/devices/platform/sony-laptop */
OBJ_sony_fanspeed,
OBJ_if_gw,
OBJ_ioscheduler,
OBJ_gw_iface,
OBJ_gw_ip,
OBJ_laptop_mode,
OBJ_pb_battery,
OBJ_voltage_mv,
OBJ_voltage_v,
OBJ_wireless_essid,
OBJ_wireless_mode,
OBJ_wireless_bitrate,
OBJ_wireless_ap,
OBJ_wireless_link_qual,
OBJ_wireless_link_qual_max,
OBJ_wireless_link_qual_perc,
OBJ_wireless_link_bar,
#endif /* __linux__ */
#if defined(__FreeBSD__) || defined(__linux__)
OBJ_if_up,
#endif
OBJ_if_empty,
OBJ_if_match,
OBJ_if_existing,
OBJ_if_mounted,
OBJ_if_running,
OBJ_if_updatenr,
OBJ_top,
OBJ_top_mem,
OBJ_top_time,
#ifdef IOSTATS
OBJ_top_io,
#endif
OBJ_tail,
OBJ_head,
OBJ_lines,
OBJ_words,
OBJ_kernel,
OBJ_loadavg,
OBJ_machine,
OBJ_mails,
OBJ_new_mails,
OBJ_seen_mails,
OBJ_unseen_mails,
OBJ_flagged_mails,
OBJ_unflagged_mails,
OBJ_format_time,
OBJ_forwarded_mails,
OBJ_unforwarded_mails,
OBJ_replied_mails,
OBJ_unreplied_mails,
OBJ_draft_mails,
OBJ_trashed_mails,
OBJ_mboxscan,
OBJ_mem,
OBJ_memeasyfree,
OBJ_memfree,
OBJ_memgauge,
#ifdef X11
OBJ_memgraph,
#endif /* X11 */
OBJ_membar,
OBJ_memmax,
OBJ_memperc,
OBJ_mixer,
OBJ_mixerl,
OBJ_mixerr,
OBJ_mixerbar,
OBJ_mixerlbar,
OBJ_mixerrbar,
OBJ_if_mixer_mute,
#ifdef X11
OBJ_monitor,
OBJ_monitor_number,
OBJ_desktop,
OBJ_desktop_number,
OBJ_desktop_name,
#endif /* X11 */
OBJ_nameserver,
OBJ_nodename,
OBJ_nvidia,
OBJ_pre_exec,
OBJ_cmdline_to_pid,
OBJ_pid_chroot,
OBJ_pid_cmdline,
OBJ_pid_cwd,
OBJ_pid_environ,
OBJ_pid_environ_list,
OBJ_pid_exe,
OBJ_pid_nice,
OBJ_pid_openfiles,
OBJ_pid_parent,
OBJ_pid_priority,
OBJ_pid_state,
OBJ_pid_state_short,
OBJ_pid_stderr,
OBJ_pid_stdin,
OBJ_pid_stdout,
OBJ_pid_threads,
OBJ_pid_thread_list,
OBJ_pid_time_kernelmode,
OBJ_pid_time_usermode,
OBJ_pid_time,
OBJ_pid_uid,
OBJ_pid_euid,
OBJ_pid_suid,
OBJ_pid_fsuid,
OBJ_pid_gid,
OBJ_pid_egid,
OBJ_pid_sgid,
OBJ_pid_fsgid,
OBJ_pid_read,
OBJ_pid_vmpeak,
OBJ_pid_vmsize,
OBJ_pid_vmlck,
OBJ_pid_vmhwm,
OBJ_pid_vmrss,
OBJ_pid_vmdata,
OBJ_pid_vmstk,
OBJ_pid_vmexe,
OBJ_pid_vmlib,
OBJ_pid_vmpte,
OBJ_pid_write,
OBJ_gid_name,
OBJ_uid_name,
OBJ_processes,
OBJ_running_processes,
OBJ_shadecolor,
OBJ_outlinecolor,
OBJ_stippled_hr,
OBJ_swap,
OBJ_swapfree,
OBJ_swapbar,
OBJ_swapmax,
OBJ_swapperc,
OBJ_sysname,
OBJ_text,
OBJ_threads,
OBJ_running_threads,
OBJ_time,
OBJ_utime,
OBJ_tztime,
OBJ_totaldown,
OBJ_totalup,
OBJ_updates,
OBJ_upspeed,
OBJ_upspeedf,
#ifdef X11
OBJ_upspeedgraph,
#endif /* X11 */
OBJ_uptime,
OBJ_uptime_short,
OBJ_user_names,
OBJ_user_terms,
OBJ_user_times,
OBJ_user_time,
OBJ_user_number,
OBJ_imap_messages,
OBJ_imap_unseen,
OBJ_pop3_unseen,
OBJ_pop3_used,
#if (defined(__FreeBSD__) || defined(__FreeBSD_kernel__) \
|| defined(__OpenBSD__)) && (defined(i386) || defined(__i386__))
OBJ_apm_adapter,
OBJ_apm_battery_time,
OBJ_apm_battery_life,
#endif /* __FreeBSD__ __OpenBSD__ */
#ifdef __OpenBSD__
OBJ_obsd_sensors_temp,
OBJ_obsd_sensors_fan,
OBJ_obsd_sensors_volt,
OBJ_obsd_vendor,
OBJ_obsd_product,
#endif /* __OpenBSD__ */
#ifdef MPD
OBJ_mpd_title,
OBJ_mpd_artist,
OBJ_mpd_album,
OBJ_mpd_random,
OBJ_mpd_repeat,
OBJ_mpd_vol,
OBJ_mpd_bitrate,
OBJ_mpd_status,
OBJ_mpd_bar,
OBJ_mpd_elapsed,
OBJ_mpd_length,
OBJ_mpd_track,
OBJ_mpd_name,
OBJ_mpd_file,
OBJ_mpd_percent,
OBJ_mpd_smart,
OBJ_if_mpd_playing,
#endif /* MPD */
#ifdef MOC
OBJ_moc_state,
OBJ_moc_file,
OBJ_moc_title,
OBJ_moc_artist,
OBJ_moc_song,
OBJ_moc_album,
OBJ_moc_totaltime,
OBJ_moc_timeleft,
OBJ_moc_curtime,
OBJ_moc_bitrate,
OBJ_moc_rate,
#endif /* MOC */
#ifdef XMMS2
OBJ_xmms2_artist,
OBJ_xmms2_album,
OBJ_xmms2_title,
OBJ_xmms2_genre,
OBJ_xmms2_comment,
OBJ_xmms2_url,
OBJ_xmms2_date,
OBJ_xmms2_tracknr,
OBJ_xmms2_bitrate,
OBJ_xmms2_id,
OBJ_xmms2_duration,
OBJ_xmms2_elapsed,
OBJ_xmms2_size,
OBJ_xmms2_percent,
OBJ_xmms2_status,
#ifdef X11
OBJ_xmms2_bar,
#endif /* X11 */
OBJ_xmms2_smart,
OBJ_xmms2_playlist,
OBJ_xmms2_timesplayed,
OBJ_if_xmms2_connected,
#endif /* XMMS2 */
#ifdef AUDACIOUS
OBJ_audacious_status,
OBJ_audacious_title,
OBJ_audacious_length,
OBJ_audacious_length_seconds,
OBJ_audacious_position,
OBJ_audacious_position_seconds,
OBJ_audacious_bitrate,
OBJ_audacious_frequency,
OBJ_audacious_channels,
OBJ_audacious_filename,
OBJ_audacious_playlist_length,
OBJ_audacious_playlist_position,
OBJ_audacious_main_volume,
#ifdef X11
OBJ_audacious_bar,
#endif /* X11 */
#endif /* AUDACIOUS */
#ifdef BMPX
OBJ_bmpx_title,
OBJ_bmpx_artist,
OBJ_bmpx_album,
OBJ_bmpx_track,
OBJ_bmpx_uri,
OBJ_bmpx_bitrate,
#endif /* BMPX */
#ifdef EVE
OBJ_eve,
#endif /* EVE */
#ifdef HAVE_CURL
OBJ_curl,
#endif /* HAVE_CURL */
#ifdef RSS
OBJ_rss,
#endif /* RSS */
#ifdef WEATHER
OBJ_weather,
#endif /* WEATHER */
#ifdef XOAP
OBJ_weather_forecast,
#endif /* XOAP */
#ifdef HAVE_LUA
OBJ_lua,
OBJ_lua_parse,
OBJ_lua_bar,
OBJ_lua_gauge,
#ifdef X11
OBJ_lua_graph,
#endif /* X11 */
#endif /* HAVE_LUA */
#ifdef TCP_PORT_MONITOR
OBJ_tcp_portmon,
#endif /* TCP_PORT_MONITOR */
#ifdef HAVE_ICONV
OBJ_iconv_start,
OBJ_iconv_stop,
#endif /* HAVE_ICONV */
#ifdef HDDTEMP
OBJ_hddtemp,
#endif /* HDDTEMP */
OBJ_include,
OBJ_blink,
OBJ_to_bytes,
OBJ_scroll,
OBJ_combine,
OBJ_entropy_avail,
OBJ_entropy_perc,
OBJ_entropy_poolsize,
OBJ_entropy_bar,
#ifdef APCUPSD
OBJ_apcupsd,
OBJ_apcupsd_name,
OBJ_apcupsd_model,
OBJ_apcupsd_upsmode,
OBJ_apcupsd_cable,
OBJ_apcupsd_status,
OBJ_apcupsd_linev,
OBJ_apcupsd_load,
OBJ_apcupsd_loadbar,
OBJ_apcupsd_loadgauge,
#ifdef X11
OBJ_apcupsd_loadgraph,
#endif /* X11 */
OBJ_apcupsd_charge,
OBJ_apcupsd_timeleft,
OBJ_apcupsd_temp,
OBJ_apcupsd_lastxfer,
#endif /* APCUPSD */
};
/* text object callbacks */
struct obj_cb {
/* text object: print obj's output to p */
@ -531,7 +93,6 @@ struct text_object {
char verbatim_output;
void *special_data;
int type;
long line;
struct obj_cb callbacks;
};

503
src/top.c
View File

@ -29,6 +29,7 @@
*
*/
#include "prioqueue.h"
#include "top.h"
#include "logging.h"
@ -595,25 +596,11 @@ static void calc_io_each(void)
* Find the top processes *
******************************************/
/* free a sp_process structure */
static void free_sp(struct sorted_process *sp)
/* cpu comparison function for prio queue */
static int compare_cpu(void *va, void *vb)
{
free(sp);
}
struct process *a = va, *b = vb;
/* create a new sp_process structure */
static struct sorted_process *malloc_sp(struct process *proc)
{
struct sorted_process *sp;
sp = malloc(sizeof(struct sorted_process));
memset(sp, 0, sizeof(struct sorted_process));
sp->proc = proc;
return sp;
}
/* cpu comparison function for insert_sp_element */
static int compare_cpu(struct process *a, struct process *b)
{
if (a->amount < b->amount) {
return 1;
} else if (a->amount > b->amount) {
@ -623,9 +610,11 @@ static int compare_cpu(struct process *a, struct process *b)
}
}
/* mem comparison function for insert_sp_element */
static int compare_mem(struct process *a, struct process *b)
/* mem comparison function for prio queue */
static int compare_mem(void *va, void *vb)
{
struct process *a = va, *b = vb;
if (a->rss < b->rss) {
return 1;
} else if (a->rss > b->rss) {
@ -635,16 +624,20 @@ static int compare_mem(struct process *a, struct process *b)
}
}
/* CPU time comparision function for insert_sp_element */
static int compare_time(struct process *a, struct process *b)
/* CPU time comparision function for prio queue */
static int compare_time(void *va, void *vb)
{
struct process *a = va, *b = vb;
return b->total_cpu_time - a->total_cpu_time;
}
#ifdef IOSTATS
/* I/O comparision function for insert_sp_element */
static int compare_io(struct process *a, struct process *b)
/* I/O comparision function for prio queue */
static int compare_io(void *va, void *vb)
{
struct process *a = va, *b = vb;
if (a->io_perc < b->io_perc) {
return 1;
} else if (a->io_perc > b->io_perc) {
@ -655,78 +648,6 @@ static int compare_io(struct process *a, struct process *b)
}
#endif /* IOSTATS */
/* insert this process into the list in a sorted fashion,
* or destroy it if it doesn't fit on the list */
static int insert_sp_element(struct sorted_process *sp_cur,
struct sorted_process **p_sp_head, struct sorted_process **p_sp_tail,
int max_elements, int compare_funct(struct process *, struct process *))
{
struct sorted_process *sp_readthru = NULL, *sp_destroy = NULL;
int did_insert = 0, x = 0;
if (*p_sp_head == NULL) {
*p_sp_head = sp_cur;
*p_sp_tail = sp_cur;
return 1;
}
for (sp_readthru = *p_sp_head, x = 0;
sp_readthru != NULL && x < max_elements;
sp_readthru = sp_readthru->less, x++) {
if (compare_funct(sp_readthru->proc, sp_cur->proc) > 0 && !did_insert) {
/* sp_cur is bigger than sp_readthru
* so insert it before sp_readthru */
sp_cur->less = sp_readthru;
if (sp_readthru == *p_sp_head) {
/* insert as the new head of the list */
*p_sp_head = sp_cur;
} else {
/* insert inside the list */
sp_readthru->greater->less = sp_cur;
sp_cur->greater = sp_readthru->greater;
}
sp_readthru->greater = sp_cur;
/* element was inserted, so increase the counter */
did_insert = ++x;
}
}
if (x < max_elements && sp_readthru == NULL && !did_insert) {
/* sp_cur is the smallest element and list isn't full,
* so insert at the end */
(*p_sp_tail)->less = sp_cur;
sp_cur->greater = *p_sp_tail;
*p_sp_tail = sp_cur;
did_insert = x;
} else if (x >= max_elements) {
/* We inserted an element and now the list is too big by one.
* Destroy the smallest element */
sp_destroy = *p_sp_tail;
*p_sp_tail = sp_destroy->greater;
(*p_sp_tail)->less = NULL;
free_sp(sp_destroy);
}
if (!did_insert) {
/* sp_cur wasn't added to the sorted list, so destroy it */
free_sp(sp_cur);
}
return did_insert;
}
/* copy the procs in the sorted list to the array, and destroy the list */
static void sp_acopy(struct sorted_process *sp_head, struct process **ar, int max_size)
{
struct sorted_process *sp_cur, *sp_tmp;
int x;
sp_cur = sp_head;
for (x = 0; x < max_size && sp_cur != NULL; x++) {
ar[x] = sp_cur->proc;
sp_tmp = sp_cur;
sp_cur = sp_cur->less;
free_sp(sp_tmp);
}
}
/* ****************************************************************** *
* Get a sorted list of the top cpu hogs and top mem hogs. *
* Results are stored in the cpu,mem arrays in decreasing order[0-9]. *
@ -739,14 +660,14 @@ void process_find_top(struct process **cpu, struct process **mem,
#endif /* IOSTATS */
)
{
struct sorted_process *spc_head = NULL, *spc_tail = NULL, *spc_cur = NULL;
struct sorted_process *spm_head = NULL, *spm_tail = NULL, *spm_cur = NULL;
struct sorted_process *spt_head = NULL, *spt_tail = NULL, *spt_cur = NULL;
prio_queue_t cpu_queue, mem_queue, time_queue
#ifdef IOSTATS
struct sorted_process *spi_head = NULL, *spi_tail = NULL, *spi_cur = NULL;
#endif /* IOSTATS */
, io_queue
#endif
;
struct process *cur_proc = NULL;
unsigned long long total = 0;
int i;
if (!top_cpu && !top_mem && !top_time
#ifdef IOSTATS
@ -757,6 +678,24 @@ void process_find_top(struct process **cpu, struct process **mem,
return;
}
cpu_queue = init_prio_queue();
pq_set_compare(cpu_queue, &compare_cpu);
pq_set_max_size(cpu_queue, MAX_SP);
mem_queue = init_prio_queue();
pq_set_compare(mem_queue, &compare_mem);
pq_set_max_size(mem_queue, MAX_SP);
time_queue = init_prio_queue();
pq_set_compare(time_queue, &compare_time);
pq_set_max_size(time_queue, MAX_SP);
#ifdef IOSTATS
io_queue = init_prio_queue();
pq_set_compare(io_queue, &compare_io);
pq_set_max_size(io_queue, MAX_SP);
#endif
total = calc_cpu_total(); /* calculate the total of the processor */
update_process_table(); /* update the table with process list */
calc_cpu_each(total); /* and then the percentage for each task */
@ -769,131 +708,40 @@ void process_find_top(struct process **cpu, struct process **mem,
while (cur_proc != NULL) {
if (top_cpu) {
spc_cur = malloc_sp(cur_proc);
insert_sp_element(spc_cur, &spc_head, &spc_tail, MAX_SP,
&compare_cpu);
insert_prio_elem(cpu_queue, cur_proc);
}
if (top_mem) {
spm_cur = malloc_sp(cur_proc);
insert_sp_element(spm_cur, &spm_head, &spm_tail, MAX_SP,
&compare_mem);
insert_prio_elem(mem_queue, cur_proc);
}
if (top_time) {
spt_cur = malloc_sp(cur_proc);
insert_sp_element(spt_cur, &spt_head, &spt_tail, MAX_SP,
&compare_time);
insert_prio_elem(time_queue, cur_proc);
}
#ifdef IOSTATS
if (top_io) {
spi_cur = malloc_sp(cur_proc);
insert_sp_element(spi_cur, &spi_head, &spi_tail, MAX_SP,
&compare_io);
insert_prio_elem(io_queue, cur_proc);
}
#endif /* IOSTATS */
cur_proc = cur_proc->next;
}
if (top_cpu) sp_acopy(spc_head, cpu, MAX_SP);
if (top_mem) sp_acopy(spm_head, mem, MAX_SP);
if (top_time) sp_acopy(spt_head, ptime, MAX_SP);
for (i = 0; i < MAX_SP; i++) {
if (top_cpu)
cpu[i] = pop_prio_elem(cpu_queue);
if (top_mem)
mem[i] = pop_prio_elem(mem_queue);
if (top_time)
ptime[i] = pop_prio_elem(time_queue);
#ifdef IOSTATS
if (top_io) sp_acopy(spi_head, io, MAX_SP);
if (top_io)
io[i] = pop_prio_elem(io_queue);
#endif /* IOSTATS */
}
struct top_data {
int num;
int type;
int was_parsed;
char *s;
};
int parse_top_args(const char *s, const char *arg, struct text_object *obj)
{
struct top_data *td;
char buf[64];
int n;
if (!arg) {
NORM_ERR("top needs arguments");
return 0;
}
if (obj->data.opaque) {
return 1;
}
if (s[3] == 0) {
obj->type = OBJ_top;
top_cpu = 1;
} else if (strcmp(&s[3], "_mem") == EQUAL) {
obj->type = OBJ_top_mem;
top_mem = 1;
} else if (strcmp(&s[3], "_time") == EQUAL) {
obj->type = OBJ_top_time;
top_time = 1;
free_prio_queue(cpu_queue);
free_prio_queue(mem_queue);
free_prio_queue(time_queue);
#ifdef IOSTATS
} else if (strcmp(&s[3], "_io") == EQUAL) {
obj->type = OBJ_top_io;
top_io = 1;
free_prio_queue(io_queue);
#endif /* IOSTATS */
} else {
#ifdef IOSTATS
NORM_ERR("Must be top, top_mem, top_time or top_io");
#else /* IOSTATS */
NORM_ERR("Must be top, top_mem or top_time");
#endif /* IOSTATS */
return 0;
}
obj->data.opaque = td = malloc(sizeof(struct top_data));
memset(td, 0, sizeof(struct top_data));
td->s = strndup(arg, text_buffer_size);
if (sscanf(arg, "%63s %i", buf, &n) == 2) {
if (strcmp(buf, "name") == EQUAL) {
td->type = TOP_NAME;
} else if (strcmp(buf, "cpu") == EQUAL) {
td->type = TOP_CPU;
} else if (strcmp(buf, "pid") == EQUAL) {
td->type = TOP_PID;
} else if (strcmp(buf, "mem") == EQUAL) {
td->type = TOP_MEM;
} else if (strcmp(buf, "time") == EQUAL) {
td->type = TOP_TIME;
} else if (strcmp(buf, "mem_res") == EQUAL) {
td->type = TOP_MEM_RES;
} else if (strcmp(buf, "mem_vsize") == EQUAL) {
td->type = TOP_MEM_VSIZE;
#ifdef IOSTATS
} else if (strcmp(buf, "io_read") == EQUAL) {
td->type = TOP_READ_BYTES;
} else if (strcmp(buf, "io_write") == EQUAL) {
td->type = TOP_WRITE_BYTES;
} else if (strcmp(buf, "io_perc") == EQUAL) {
td->type = TOP_IO_PERC;
#endif /* IOSTATS */
} else {
NORM_ERR("invalid type arg for top");
#ifdef IOSTATS
NORM_ERR("must be one of: name, cpu, pid, mem, time, mem_res, mem_vsize, "
"io_read, io_write, io_perc");
#else /* IOSTATS */
NORM_ERR("must be one of: name, cpu, pid, mem, time, mem_res, mem_vsize");
#endif /* IOSTATS */
return 0;
}
if (n < 1 || n > 10) {
NORM_ERR("invalid num arg for top. Must be between 1 and 10.");
return 0;
} else {
td->num = n - 1;
}
} else {
NORM_ERR("invalid argument count for top");
return 0;
}
return 1;
}
static char *format_time(unsigned long timeval, const int width)
@ -936,6 +784,13 @@ static char *format_time(unsigned long timeval, const int width)
return strndup("<inf>", text_buffer_size);
}
struct top_data {
struct process **list;
int num;
int was_parsed;
char *s;
};
static unsigned int top_name_width = 15;
/* return zero on success, non-zero otherwise */
@ -946,97 +801,74 @@ int set_top_name_width(const char *s)
return !(sscanf(s, "%u", &top_name_width) == 1);
}
void print_top(struct text_object *obj, char *p, int p_max_size)
static void print_top_name(struct text_object *obj, char *p, int p_max_size)
{
struct information *cur = &info;
struct top_data *td = obj->data.opaque;
struct process **needed = 0;
int width;
if (!td)
if (!td || !td->list || !td->list[td->num])
return;
switch (obj->type) {
case OBJ_top:
needed = cur->cpu;
break;
case OBJ_top_mem:
needed = cur->memu;
break;
case OBJ_top_time:
needed = cur->time;
break;
#ifdef IOSTATS
case OBJ_top_io:
needed = cur->io;
break;
#endif /* IOSTATS */
default:
return;
}
if (needed[td->num]) {
char *timeval;
switch (td->type) {
case TOP_NAME:
width = MIN(p_max_size, (int)top_name_width + 1);
snprintf(p, width + 1, "%-*s", width,
needed[td->num]->name);
break;
case TOP_CPU:
width = MIN(p_max_size, 7);
snprintf(p, width, "%6.2f",
needed[td->num]->amount);
break;
case TOP_PID:
width = MIN(p_max_size, 6);
snprintf(p, width, "%5i",
needed[td->num]->pid);
break;
case TOP_MEM:
/* Calculate a percentage of residential mem from total mem available.
* Since rss is bytes and memmax kilobytes, dividing by 10 suffices here. */
width = MIN(p_max_size, 7);
snprintf(p, width, "%6.2f",
(float) ((float)needed[td->num]->rss / cur->memmax) / 10);
break;
case TOP_TIME:
width = MIN(p_max_size, 10);
timeval = format_time(
needed[td->num]->total_cpu_time, 9);
snprintf(p, width, "%9s", timeval);
free(timeval);
break;
case TOP_MEM_RES:
human_readable(needed[td->num]->rss,
p, p_max_size);
break;
case TOP_MEM_VSIZE:
human_readable(needed[td->num]->vsize,
p, p_max_size);
break;
#ifdef IOSTATS
case TOP_READ_BYTES:
human_readable(needed[td->num]->read_bytes / update_interval,
p, p_max_size);
break;
case TOP_WRITE_BYTES:
human_readable(needed[td->num]->write_bytes / update_interval,
p, p_max_size);
break;
case TOP_IO_PERC:
width = MIN(p_max_size, 7);
snprintf(p, width, "%6.2f",
needed[td->num]->io_perc);
break;
#endif
}
}
width = MIN(p_max_size, (int)top_name_width + 1);
snprintf(p, width + 1, "%-*s", width, td->list[td->num]->name);
}
void free_top(struct text_object *obj)
static void print_top_mem(struct text_object *obj, char *p, int p_max_size)
{
struct top_data *td = obj->data.opaque;
int width;
if (!td || !td->list || !td->list[td->num])
return;
width = MIN(p_max_size, 7);
snprintf(p, width, "%6.2f", (float) ((float)td->list[td->num]->rss / info.memmax) / 10);
}
static void print_top_time(struct text_object *obj, char *p, int p_max_size)
{
struct top_data *td = obj->data.opaque;
int width;
char *timeval;
if (!td || !td->list || !td->list[td->num])
return;
width = MIN(p_max_size, 10);
timeval = format_time(td->list[td->num]->total_cpu_time, 9);
snprintf(p, width, "%9s", timeval);
free(timeval);
}
#define PRINT_TOP_GENERATOR(name, width, fmt, field) \
static void print_top_##name(struct text_object *obj, char *p, int p_max_size) \
{ \
struct top_data *td = obj->data.opaque; \
if (!td || !td->list || !td->list[td->num]) \
return; \
snprintf(p, MIN(p_max_size, width), fmt, td->list[td->num]->field); \
}
#define PRINT_TOP_HR_GENERATOR(name, field, denom) \
static void print_top_##name(struct text_object *obj, char *p, int p_max_size) \
{ \
struct top_data *td = obj->data.opaque; \
if (!td || !td->list || !td->list[td->num]) \
return; \
human_readable(td->list[td->num]->field / denom, p, p_max_size); \
}
PRINT_TOP_GENERATOR(cpu, 7, "%6.2f", amount)
PRINT_TOP_GENERATOR(pid, 6, "%5i", pid)
PRINT_TOP_HR_GENERATOR(mem_res, rss, 1)
PRINT_TOP_HR_GENERATOR(mem_vsize, vsize, 1)
#ifdef IOSTATS
PRINT_TOP_HR_GENERATOR(read_bytes, read_bytes, update_interval)
PRINT_TOP_HR_GENERATOR(write_bytes, write_bytes, update_interval)
PRINT_TOP_GENERATOR(io_perc, 7, "%6.2f", io_perc)
#endif /* IOSTATS */
static void free_top(struct text_object *obj)
{
struct top_data *td = obj->data.opaque;
@ -1047,3 +879,92 @@ void free_top(struct text_object *obj)
free(obj->data.opaque);
obj->data.opaque = NULL;
}
int parse_top_args(const char *s, const char *arg, struct text_object *obj)
{
struct top_data *td;
char buf[64];
int n;
if (!arg) {
NORM_ERR("top needs arguments");
return 0;
}
obj->data.opaque = td = malloc(sizeof(struct top_data));
memset(td, 0, sizeof(struct top_data));
if (s[3] == 0) {
td->list = info.cpu;
top_cpu = 1;
} else if (strcmp(&s[3], "_mem") == EQUAL) {
td->list = info.memu;
top_mem = 1;
} else if (strcmp(&s[3], "_time") == EQUAL) {
td->list = info.time;
top_time = 1;
#ifdef IOSTATS
} else if (strcmp(&s[3], "_io") == EQUAL) {
td->list = info.io;
top_io = 1;
#endif /* IOSTATS */
} else {
#ifdef IOSTATS
NORM_ERR("Must be top, top_mem, top_time or top_io");
#else /* IOSTATS */
NORM_ERR("Must be top, top_mem or top_time");
#endif /* IOSTATS */
free(obj->data.opaque);
obj->data.opaque = 0;
return 0;
}
td->s = strndup(arg, text_buffer_size);
if (sscanf(arg, "%63s %i", buf, &n) == 2) {
if (strcmp(buf, "name") == EQUAL) {
obj->callbacks.print = &print_top_name;
} else if (strcmp(buf, "cpu") == EQUAL) {
obj->callbacks.print = &print_top_cpu;
} else if (strcmp(buf, "pid") == EQUAL) {
obj->callbacks.print = &print_top_pid;
} else if (strcmp(buf, "mem") == EQUAL) {
obj->callbacks.print = &print_top_mem;
add_update_callback(&update_meminfo);
} else if (strcmp(buf, "time") == EQUAL) {
obj->callbacks.print = &print_top_time;
} else if (strcmp(buf, "mem_res") == EQUAL) {
obj->callbacks.print = &print_top_mem_res;
} else if (strcmp(buf, "mem_vsize") == EQUAL) {
obj->callbacks.print = &print_top_mem_vsize;
#ifdef IOSTATS
} else if (strcmp(buf, "io_read") == EQUAL) {
obj->callbacks.print = &print_top_read_bytes;
} else if (strcmp(buf, "io_write") == EQUAL) {
obj->callbacks.print = &print_top_write_bytes;
} else if (strcmp(buf, "io_perc") == EQUAL) {
obj->callbacks.print = &print_top_io_perc;
#endif /* IOSTATS */
} else {
NORM_ERR("invalid type arg for top");
#ifdef IOSTATS
NORM_ERR("must be one of: name, cpu, pid, mem, time, mem_res, mem_vsize, "
"io_read, io_write, io_perc");
#else /* IOSTATS */
NORM_ERR("must be one of: name, cpu, pid, mem, time, mem_res, mem_vsize");
#endif /* IOSTATS */
return 0;
}
if (n < 1 || n > 10) {
NORM_ERR("invalid num arg for top. Must be between 1 and 10.");
return 0;
} else {
td->num = n - 1;
}
} else {
NORM_ERR("invalid argument count for top");
return 0;
}
obj->callbacks.free = &free_top;
return 1;
}

View File

@ -146,8 +146,6 @@ void process_find_top(struct process **, struct process **, struct process **
struct process *get_process_by_name(const char *);
int parse_top_args(const char *s, const char *arg, struct text_object *obj);
void print_top(struct text_object *, char *, int);
void free_top(struct text_object *);
/* return zero on success, non-zero otherwise */
int set_top_name_width(const char *);