//
// Conky update function for apcupsd data
//
-void update_apcupsd(void) {
+int update_apcupsd(void) {
int i;
APCUPSD_S apc;
// "atomically" copy the data into working set
//
memcpy(info.apcupsd.items, apc.items, sizeof(info.apcupsd.items));
- return;
+ return 0;
}
} APCUPSD_S, *PAPCUPSD_S;
/* Service routine for the conky main thread */
-void update_apcupsd(void);
+int update_apcupsd(void);
#endif /*APCUPSD_H_*/
}
#endif /* HAVE_STRNDUP */
-void update_uname(void)
+int update_uname(void)
{
uname(&info.uname_s);
+ return 0;
}
double get_time(void)
* Populated while initialising text objects in construct_text_object(). */
static struct update_cb {
struct update_cb *next;
- void (*func)(void);
+ int (*func)(void);
pthread_t thread;
sem_t start_wait, end_wait;
/* Register an update callback. Don't allow duplicates, to minimise side
* effects and overhead. */
-void add_update_callback(void (*func)(void))
+void add_update_callback(int (*func)(void))
{
struct update_cb *uc = &update_cb_head;
while (1) {
if (sem_wait(&ucb->start_wait)) pthread_exit(NULL);
if (ucb->running == 0) pthread_exit(NULL);
- (*ucb->func)();
+ if((*ucb->func)()) {
+ ucb->next = ucb; //this is normally not be possible, so we use it to show that there was a critical error
+ sem_post(&ucb->end_wait);
+ sem_post(&ucb->end_wait);
+ pthread_exit(NULL);
+ }
if (sem_post(&ucb->end_wait)) pthread_exit(NULL);
}
}
}
/* need to synchronise here, otherwise locking is needed (as data
* would be printed with some update callbacks still running) */
- for (uc = update_cb_head.next; uc; uc = uc->next)
+ for (uc = update_cb_head.next; uc; uc = uc->next) {
sem_wait(&uc->end_wait);
+ if(uc == uc->next) {
+ pthread_join(uc->thread, NULL);
+ free(uc);
+ exit(EXIT_FAILURE);
+ }
+ }
/* XXX: move the following into the update_meminfo() functions? */
if (no_buffers) {
#include <sys/socket.h>
#include "text_object.h"
-void add_update_callback(void (*func)(void));
+void add_update_callback(int (*func)(void));
void free_update_callbacks(void);
void start_update_threading(void);
void strfold(char *start, int count);
int check_mount(char *s);
void prepare_update(void);
-void update_uptime(void);
-void update_meminfo(void);
-void update_net_stats(void);
-void update_cpu_usage(void);
-void update_total_processes(void);
-void update_uname(void);
-void update_threads(void);
-void update_running_processes(void);
+int update_uptime(void);
+int update_meminfo(void);
+int update_net_stats(void);
+int update_cpu_usage(void);
+int update_total_processes(void);
+int update_uname(void);
+int update_threads(void);
+int update_running_processes(void);
void update_stuff(void);
char get_freq(char *, size_t, const char *, int, unsigned int);
void print_voltage_mv(struct text_object *, char *, int);
void print_voltage_v(struct text_object *, char *, int);
-void update_load_average(void);
-void update_top(void);
+int update_load_average(void);
+int update_top(void);
void free_all_processes(void);
struct process *get_first_process(void);
void get_cpu_count(void);
void format_seconds_short(char *buf, unsigned int n, long t);
#ifdef X11
-void update_x11info(void);
+int update_x11info(void);
#endif
int round_to_int_temp(float);
char *ps, *pe;
int special_index = 0; /* specials index */
+ if(! b) return;
for (ps = b, pe = b; *pe; pe++) {
if (*pe == '\n') {
*pe = '\0';
buff_in[0] = 0;
#endif /* HAVE_ICONV */
+ if(! p) return;
+
p[0] = 0;
obj = root.next;
while (obj && p_max_size > 0) {
}
#endif
-void clean_up(void *memtofree1, void* memtofree2)
-{
+void clean_up_without_threads(void *memtofree1, void* memtofree2) {
int i;
- free_update_callbacks();
-
#ifdef NCURSES
if(output_methods & TO_NCURSES) {
endwin();
}
}
+void clean_up(void *memtofree1, void* memtofree2)
+{
+ free_update_callbacks();
+ clean_up_without_threads(memtofree1, memtofree2);
+}
+
static int string_to_bool(const char *s)
{
if (!s) {
extern struct information info;
/* defined in users.c */
-void update_users(void);
+int update_users(void);
void update_user_time(char *tty);
/* defined in conky.c */
extern struct diskio_stat stats;
struct diskio_stat *prepare_diskio_stat(const char *);
-void update_diskio(void);
+int update_diskio(void);
void clear_diskio_stats(void);
void update_diskio_values(struct diskio_stat *, unsigned int, unsigned int);
.poolsize = 0,
};
-void update_entropy(void)
+int update_entropy(void)
{
get_entropy_avail(&entropy.avail);
get_entropy_poolsize(&entropy.poolsize);
+ return 0;
}
void print_entropy_avail(struct text_object *obj, char *p, int p_max_size)
#ifndef _ENTROPY_H
#define _ENTROPY_H
-void update_entropy(void);
+int update_entropy(void);
void print_entropy_avail(struct text_object *, char *, int);
void print_entropy_perc(struct text_object *, char *, int);
void get_fs_type(const char *path, char *result);
-void update_fs_stats(void)
+int update_fs_stats(void)
{
unsigned i;
static double last_fs_update = 0.0;
if (current_update_time - last_fs_update < 13)
- return;
+ return 0;
for (i = 0; i < MAX_FS_STATS; ++i) {
if (fs_stats[i].set) {
}
}
last_fs_update = current_update_time;
+ return 0;
}
void clear_fs_stats(void)
void print_fs_used(struct text_object *, char *, int);
void print_fs_type(struct text_object *, char *, int);
-void update_fs_stats(void);
+int update_fs_stats(void);
struct fs_stat *prepare_fs_stat(const char *path);
void clear_fs_stats(void);
return 1;
}
-void update_hddtemp(void) {
+int update_hddtemp(void) {
char *data, *dev, unit, *saveptr;
short val;
static double last_hddtemp_update = 0.0;
/* limit tcp connection overhead */
if (current_update_time - last_hddtemp_update < 5)
- return;
+ return 0;
last_hddtemp_update = current_update_time;
free_hddtemp_info();
if (!(data = fetch_hddtemp_output()))
- return;
+ return 0;
if (read_hdd_val(data, &dev, &val, &unit, &saveptr)) {
free(data);
- return;
+ return 0;
}
do {
add_hddtemp_info(dev, val, unit);
} while (!read_hdd_val(NULL, &dev, &val, &unit, &saveptr));
free(data);
+ return 0;
}
void free_hddtemp(void)
void set_hddtemp_host(const char *);
void set_hddtemp_port(const char *);
-void update_hddtemp(void);
+int update_hddtemp(void);
void free_hddtemp(void);
int get_hddtemp_info(const char *, short *, char *);
#define PROC_I8K "/proc/i8k"
#define I8K_DELIM " "
static char *i8k_procbuf = NULL;
-void update_i8k(void)
+int update_i8k(void)
{
FILE *fp;
i8k_procbuf = (char *) malloc(128 * sizeof(char));
}
if ((fp = fopen(PROC_I8K, "r")) == NULL) {
- CRIT_ERR(NULL, NULL, "/proc/i8k doesn't exist! use insmod to make sure the kernel "
+ free(i8k_procbuf);
+ i8k_procbuf = NULL;
+ NORM_ERR("/proc/i8k doesn't exist! use insmod to make sure the kernel "
"driver is loaded...");
+ clean_up_without_threads(NULL, NULL);
+ free(current_mail_spool);
+ return 1;
}
memset(&i8k_procbuf[0], 0, 128);
i8k.right_fan_rpm = strtok(NULL, I8K_DELIM);
i8k.ac_status = strtok(NULL, I8K_DELIM);
i8k.buttons_status = strtok(NULL, I8K_DELIM);
+ return 0;
}
static const char *fan_status_to_string(int status)
#ifndef _I8K_H
#define _I8K_H
-void update_i8k(void);
+int update_i8k(void);
void print_i8k_left_fan_status(struct text_object *, char *, int);
void print_i8k_cpu_temp(struct text_object *, char *, int);
void print_i8k_right_fan_status(struct text_object *, char *, int);
commands: enable, disable
* Peter Tarjan (ptarjan@citromail.hu) */
-void get_ibm_acpi_fan(struct text_object *obj, char *p, int p_max_size)
+int get_ibm_acpi_fan(struct text_object *obj, char *p, int p_max_size)
{
FILE *fp;
unsigned int speed = 0;
(void)obj;
if (!p || p_max_size <= 0) {
- return;
+ return 0;
}
snprintf(fan, 127, "%s/fan", IBM_ACPI_DIR);
fclose(fp);
snprintf(p, p_max_size, "%d", speed);
+ return 0;
}
/* get the measured temperatures from the temperature sensors
#include <sys/types.h>
void get_ibm_acpi_fan(struct text_object *, char *, int);
-void get_ibm_acpi_temps(void);
+int get_ibm_acpi_temps(void);
void get_ibm_acpi_volume(struct text_object *, char *, int);
void get_ibm_acpi_brightness(struct text_object *, char *, int);
{
}
-void update_uptime(void)
+int update_uptime(void)
{
#ifdef HAVE_SYSINFO
if (!prefer_proc) {
if (!(fp = open_file("/proc/uptime", &rep))) {
info.uptime = 0.0;
- return;
+ return 0;
}
fscanf(fp, "%lf", &info.uptime);
fclose(fp);
}
+ return 0;
}
int check_mount(char *s)
/* these things are also in sysinfo except Buffers:
* (that's why I'm reading them from proc) */
-void update_meminfo(void)
+int update_meminfo(void)
{
FILE *meminfo_fp;
static int rep = 0;
info.buffers = info.cached = info.memfree = info.memeasyfree = 0;
if (!(meminfo_fp = open_file("/proc/meminfo", &rep))) {
- return;
+ return 0;
}
while (!feof(meminfo_fp)) {
info.bufmem = info.cached + info.buffers;
fclose(meminfo_fp);
+ return 0;
}
int get_laptop_mode(void)
/* Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT */
#define RT_ENTRY_FORMAT "%63s %lx %lx %x %*d %*d %*d %lx %*d %*d %*d\n"
-void update_gateway_info(void)
+int update_gateway_info(void)
{
FILE *fp;
struct in_addr ina;
if ((fp = fopen("/proc/net/route", "r")) == NULL) {
update_gateway_info_failure("fopen()");
- return;
+ return 0;
}
/* skip over the table header line, which is always present */
}
}
fclose(fp);
- return;
+ return 0;
}
void free_gateway_info(void)
snprintf(p, p_max_size, "%s", gw_info.ip);
}
-void update_net_stats(void)
+int update_net_stats(void)
{
FILE *net_dev_fp;
static int rep = 0;
/* get delta */
delta = current_update_time - last_update_time;
if (delta <= 0.0001) {
- return;
+ return 0;
}
/* open file and ignore first two lines */
if (!(net_dev_fp = open_file("/proc/net/dev", &rep))) {
clear_net_stats();
- return;
+ return 0;
}
fgets(buf, 255, net_dev_fp); /* garbage */
first = 0;
fclose(net_dev_fp);
+ return 0;
}
int result;
-void update_total_processes(void)
+int update_total_processes(void)
{
DIR *dir;
struct dirent *entry;
info.procs = 0;
if (!(dir = opendir("/proc"))) {
- return;
+ return 0;
}
while ((entry = readdir(dir))) {
if (!entry) {
/* Problem reading list of processes */
closedir(dir);
info.procs = 0;
- return;
+ return 0;
}
if (sscanf(entry->d_name, "%d%c", &ignore1, &ignore2) == 1) {
info.procs++;
}
}
closedir(dir);
+ return 0;
}
-void update_threads(void)
+int update_threads(void)
{
#ifdef HAVE_SYSINFO
if (!prefer_proc) {
if (!(fp = open_file("/proc/loadavg", &rep))) {
info.threads = 0;
- return;
+ return 0;
}
fscanf(fp, "%*f %*f %*f %*d/%hu", &info.threads);
fclose(fp);
}
+ return 0;
}
#define CPU_SAMPLE_COUNT 15
#define TMPL_LONGSTAT "%*s %llu %llu %llu %llu %llu %llu %llu %llu"
#define TMPL_SHORTSTAT "%*s %llu %llu %llu %llu"
-void update_stat(void)
+int update_stat(void)
{
FILE *stat_fp;
static int rep = 0;
pthread_mutex_lock(&last_stat_update_mutex);
if (last_stat_update == current_update_time) {
pthread_mutex_unlock(&last_stat_update_mutex);
- return;
+ return 0;
}
last_stat_update = current_update_time;
pthread_mutex_unlock(&last_stat_update_mutex);
if (info.cpu_usage) {
memset(info.cpu_usage, 0, info.cpu_count * sizeof(float));
}
- return;
+ return 0;
}
idx = 0;
}
}
fclose(stat_fp);
+ return 0;
}
-void update_running_processes(void)
+int update_running_processes(void)
{
update_stat();
+ return 0;
}
-void update_cpu_usage(void)
+int update_cpu_usage(void)
{
update_stat();
+ return 0;
}
-void update_load_average(void)
+int update_load_average(void)
{
#ifdef HAVE_GETLOADAVG
if (!prefer_proc) {
if (!(fp = open_file("/proc/loadavg", &rep))) {
info.loadavg[0] = info.loadavg[1] = info.loadavg[2] = 0.0;
- return;
+ return 0;
}
fscanf(fp, "%f %f %f", &info.loadavg[0], &info.loadavg[1],
&info.loadavg[2]);
fclose(fp);
}
+ return 0;
}
/***********************************************************/
snprintf(buffer, n, "%s", pb_battery_info[i]);
}
-void update_top(void)
+int update_top(void)
{
process_find_top(info.cpu, info.memu, info.time
#ifdef IOSTATS
#endif
);
info.first_process = get_first_process();
+ return 0;
}
#define ENTROPY_AVAIL_PATH "/proc/sys/kernel/random/entropy_avail"
return dev_cur->memoized;
}
-void update_diskio(void)
+int update_diskio(void)
{
FILE *fp;
static int rep = 0;
stats.current_write = 0;
if (!(fp = open_file("/proc/diskstats", &rep))) {
- return;
+ return 0;
}
/* read reads and writes from all disks (minor = 0), including cd-roms
}
update_diskio_values(&stats, total_reads, total_writes);
fclose(fp);
+ return 0;
}
char *get_ioscheduler(char *);
int get_laptop_mode(void);
-void update_gateway_info(void);
+int update_gateway_info(void);
void free_gateway_info(void);
int gateway_exists(void);
void print_gateway_iface(char *, int);
int get_entropy_avail(unsigned int *);
int get_entropy_poolsize(unsigned int *);
-void update_stat(void);
+int update_stat(void);
#endif /* _LINUX_H */
#include "mail.h"
void clean_up(void *memtofree1, void* memtofree2);
+void clean_up_without_threads(void *memtofree1, void* memtofree2);
#ifndef _LOGGING_H
#define _LOGGING_H
#define CRIT_ERR(memtofree1, memtofree2, ...) \
{ NORM_ERR(__VA_ARGS__); clean_up(memtofree1, memtofree2); free(current_mail_spool); exit(EXIT_FAILURE); }
+#define THREAD_CRIT_ERR(memtofree1, memtofree2, ...) \
+ { NORM_ERR(__VA_ARGS__); clean_up_without_threads(memtofree1, memtofree2); free(current_mail_spool); return; }
+
/* debugging output */
extern int global_debug_level;
#define __DBGP(level, ...) \
return 0;
}
-void update_moc(void)
+int update_moc(void)
{
run_moc_thread(info.music_player_interval * 100000);
+ return 0;
}
};
extern struct moc_s moc;
-void update_moc(void);
+int update_moc(void);
void free_moc(void);
#endif /* MOC_H_ */
static void *update_mpd_thread(void *) __attribute__((noreturn));
-void update_mpd(void)
+int update_mpd(void)
{
int interval;
static timed_thread *thread = NULL;
if (thread)
- return;
+ return 0;
interval = info.music_player_interval * 1000000;
thread = timed_thread_create(&update_mpd_thread, &thread, interval);
if (!thread) {
NORM_ERR("Failed to create MPD timed thread");
- return;
+ return 0;
}
timed_thread_register(thread, &thread);
if (timed_thread_run(thread))
NORM_ERR("Failed to run MPD timed thread");
+ return 0;
}
/* stringMAXdup dups at most text_buffer_size bytes */
void init_mpd(void);
struct mpd_s *mpd_get_info(void);
void free_mpd(void);
-void update_mpd(void);
+int update_mpd(void);
void print_mpd_elapsed(struct text_object *, char *, int);
void print_mpd_length(struct text_object *, char *, int);
memset(&dns_data, 0, sizeof(dns_data));
}
-void update_dns_data(void)
+int update_dns_data(void)
{
FILE *fp;
char line[256];
free_dns_data();
if ((fp = fopen("/etc/resolv.conf", "r")) == NULL)
- return;
+ return 0;
while(!feof(fp)) {
if (fgets(line, 255, fp) == NULL) {
break;
}
}
fclose(fp);
+ return 0;
}
void parse_nameserver_arg(struct text_object *obj, const char *arg)
void free_if_up(struct text_object *);
void free_dns_data(void);
-void update_dns_data(void);
+int update_dns_data(void);
void parse_nameserver_arg(struct text_object *, const char *);
void print_nameserver(struct text_object *, char *, int);
return 0;
}
-void tcp_portmon_update(void)
+int tcp_portmon_update(void)
{
update_tcp_port_monitor_collection(pmc);
+ return 0;
}
int tcp_portmon_clear(void)
int tcp_portmon_init(struct text_object *, const char *);
int tcp_portmon_action(struct text_object *, char *, int);
-void tcp_portmon_update(void);
+int tcp_portmon_update(void);
int tcp_portmon_clear(void);
int tcp_portmon_set_max_connections(int);
void tcp_portmon_free(struct text_object *);
}
}
-void update_users(void)
+int update_users(void)
{
struct information *current_info = &info;
char temp[BUFLEN] = "";
current_info->users.times = malloc(text_buffer_size);
strncpy(current_info->users.times, "broken", text_buffer_size);
}
+ return 0;
}
}
}
-void update_x11info(void)
+int update_x11info(void)
{
struct information *current_info = &info;
if (x_initialised != YES)
- return;
+ return 0;
current_info->x11.monitor.number = XScreenCount(display);
current_info->x11.monitor.current = XDefaultScreen(display);
+ return 0;
}
#ifdef OWN_WINDOW