X-Git-Url: https://git.xinqibao.xyz/slstatus.git/blobdiff_plain/6f011743921db04e5513df45c5ac4b2c752d52de..8f5219b6dab5a1c9b7f92362a34aacfd393fa0e4:/slstatus.c diff --git a/slstatus.c b/slstatus.c index 47bd4c9..d0d1767 100644 --- a/slstatus.c +++ b/slstatus.c @@ -1,12 +1,11 @@ /* See LICENSE file for copyright and license details. */ - #include #include +#include #include #include #include #include -#include #include #include #include @@ -36,7 +35,6 @@ struct arg { const char *args; }; -static const char *bprintf(const char *fmt, ...); static const char *battery_perc(const char *bat); static const char *battery_power(const char *bat); static const char *battery_state(const char *bat); @@ -50,7 +48,8 @@ static const char *disk_used(const char *mnt); static const char *entropy(void); static const char *gid(void); static const char *hostname(void); -static const char *ip(const char *iface); +static const char *ipv4(const char *iface); +static const char *ipv6(const char *iface); static const char *kernel_release(void); static const char *keyboard_indicators(void); static const char *load_avg(void); @@ -71,11 +70,8 @@ static const char *username(void); static const char *vol_perc(const char *card); static const char *wifi_perc(const char *iface); static const char *wifi_essid(const char *iface); -static void sighandler(const int signo); -static void usage(void); char *argv0; -static unsigned short int delay = 0; static unsigned short int done; static Display *dpy; @@ -99,52 +95,50 @@ bprintf(const char *fmt, ...) return buf; } -static const char * -battery_perc(const char *bat) +int +pscanf(const char *path, const char *fmt, ...) { - int n, perc; - char path[PATH_MAX]; FILE *fp; + va_list ap; + int n; - snprintf(path, sizeof(path), "%s%s%s", "/sys/class/power_supply/", bat, "/capacity"); - fp = fopen(path, "r"); - if (fp == NULL) { - warn("Failed to open file %s", path); - return UNKNOWN_STR; + if (!(fp = fopen(path, "r"))) { + warn("fopen %s: %s\n", path, strerror(errno)); + return -1; } - n = fscanf(fp, "%i", &perc); + va_start(ap, fmt); + n = vfscanf(fp, fmt, ap); + va_end(ap); fclose(fp); - if (n != 1) - return UNKNOWN_STR; - return bprintf("%d", perc); + return (n == EOF) ? -1 : n; +} + +static const char * +battery_perc(const char *bat) +{ + int perc; + char path[PATH_MAX]; + + snprintf(path, sizeof(path), "%s%s%s", "/sys/class/power_supply/", bat, "/capacity"); + return (pscanf(path, "%i", &perc) == 1) ? + bprintf("%d", perc) : unknown_str; } static const char * battery_power(const char *bat) { + int watts; char path[PATH_MAX]; - FILE *fp; - int n, watts; snprintf(path, sizeof(path), "%s%s%s", "/sys/class/power_supply/", bat, "/power_now"); - fp = fopen(path, "r"); - if (fp == NULL) { - warn("Failed to open file %s", path); - return UNKNOWN_STR; - } - n = fscanf(fp, "%i", &watts); - fclose(fp); - if (n != 1) - return UNKNOWN_STR; - - return bprintf("%d", (watts + 500000) / 1000000); + return (pscanf(path, "%i", &watts) == 1) ? + bprintf("%d", (watts + 500000) / 1000000) : unknown_str; } static const char * battery_state(const char *bat) { - FILE *fp; struct { char *state; char *symbol; @@ -155,79 +149,55 @@ battery_state(const char *bat) { "Unknown", "/" }, }; size_t i; - int n; char path[PATH_MAX], state[12]; snprintf(path, sizeof(path), "%s%s%s", "/sys/class/power_supply/", bat, "/status"); - fp = fopen(path, "r"); - if (fp == NULL) { - warn("Failed to open file %s", path); - return UNKNOWN_STR; + if (pscanf(path, "%12s", state) != 1) { + return unknown_str; } - n = fscanf(fp, "%12s", state); - fclose(fp); - if (n != 1) - return UNKNOWN_STR; for (i = 0; i < LEN(map); i++) { if (!strcmp(map[i].state, state)) { break; } } - return (i == LEN(map)) ? "?" : map[i].symbol; } static const char * cpu_freq(void) { - int n, freq; - FILE *fp; + int freq; - fp = fopen("/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq", "r"); - if (fp == NULL) { - warn("Failed to open file /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq"); - return UNKNOWN_STR; - } - n = fscanf(fp, "%i", &freq); - fclose(fp); - if (n != 1) - return UNKNOWN_STR; - - return bprintf("%d", (freq + 500) / 1000); + return (pscanf("/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq", + "%i", &freq) == 1) ? + bprintf("%d", (freq + 500) / 1000) : unknown_str; } static const char * cpu_perc(void) { - int n, perc; + struct timespec delay; + int perc; long double a[4], b[4]; - FILE *fp; - fp = fopen("/proc/stat", "r"); - if (fp == NULL) { - warn("Failed to open file /proc/stat"); - return UNKNOWN_STR; + if (pscanf("/proc/stat", "%*s %Lf %Lf %Lf %Lf", &a[0], &a[1], &a[2], + &a[3]) != 4) { + return unknown_str; } - n = fscanf(fp, "%*s %Lf %Lf %Lf %Lf", &a[0], &a[1], &a[2], &a[3]); - fclose(fp); - if (n != 4) - return UNKNOWN_STR; - delay++; - sleep(delay); + delay.tv_sec = (interval / 2) / 1000; + delay.tv_nsec = ((interval / 2) % 1000) * 1000000; + nanosleep(&delay, NULL); - fp = fopen("/proc/stat", "r"); - if (fp == NULL) { - warn("Failed to open file /proc/stat"); - return UNKNOWN_STR; + if (pscanf("/proc/stat", "%*s %Lf %Lf %Lf %Lf", &b[0], &b[1], &b[2], + &b[3]) != 4) { + return unknown_str; } - n = fscanf(fp, "%*s %Lf %Lf %Lf %Lf", &b[0], &b[1], &b[2], &b[3]); - fclose(fp); - if (n != 4) - return UNKNOWN_STR; - perc = 100 * ((b[0]+b[1]+b[2]) - (a[0]+a[1]+a[2])) / ((b[0]+b[1]+b[2]+b[3]) - (a[0]+a[1]+a[2]+a[3])); + perc = 100 * ((b[0]+b[1]+b[2]) - (a[0]+a[1]+a[2])) / + ((b[0]+b[1]+b[2]+b[3]) - (a[0]+a[1]+a[2]+a[3])); + return bprintf("%d", perc); } @@ -238,7 +208,7 @@ datetime(const char *fmt) t = time(NULL); if (strftime(buf, sizeof(buf), fmt, localtime(&t)) == 0) - return UNKNOWN_STR; + return unknown_str; return buf; } @@ -250,7 +220,7 @@ disk_free(const char *mnt) if (statvfs(mnt, &fs) < 0) { warn("Failed to get filesystem info"); - return UNKNOWN_STR; + return unknown_str; } return bprintf("%f", (float)fs.f_bsize * (float)fs.f_bfree / 1024 / 1024 / 1024); @@ -264,7 +234,7 @@ disk_perc(const char *mnt) if (statvfs(mnt, &fs) < 0) { warn("Failed to get filesystem info"); - return UNKNOWN_STR; + return unknown_str; } perc = 100 * (1.0f - ((float)fs.f_bfree / (float)fs.f_blocks)); @@ -279,7 +249,7 @@ disk_total(const char *mnt) if (statvfs(mnt, &fs) < 0) { warn("Failed to get filesystem info"); - return UNKNOWN_STR; + return unknown_str; } return bprintf("%f", (float)fs.f_bsize * (float)fs.f_blocks / 1024 / 1024 / 1024); @@ -292,7 +262,7 @@ disk_used(const char *mnt) if (statvfs(mnt, &fs) < 0) { warn("Failed to get filesystem info"); - return UNKNOWN_STR; + return unknown_str; } return bprintf("%f", (float)fs.f_bsize * ((float)fs.f_blocks - (float)fs.f_bfree) / 1024 / 1024 / 1024); @@ -301,20 +271,10 @@ disk_used(const char *mnt) static const char * entropy(void) { - int n, num; - FILE *fp; + int num; - fp= fopen("/proc/sys/kernel/random/entropy_avail", "r"); - if (fp == NULL) { - warn("Failed to open file /proc/sys/kernel/random/entropy_avail"); - return UNKNOWN_STR; - } - n = fscanf(fp, "%d", &num); - fclose(fp); - if (n != 1) - return UNKNOWN_STR; - - return bprintf("%d", num); + return (pscanf("/proc/sys/kernel/random/entropy_avail", "%d", &num) == 1) ? + bprintf("%d", num) : unknown_str; } static const char * @@ -328,22 +288,22 @@ hostname(void) { if (gethostname(buf, sizeof(buf)) == -1) { warn("hostname"); - return UNKNOWN_STR; + return unknown_str; } return buf; } static const char * -ip(const char *iface) +ipv4(const char *iface) { struct ifaddrs *ifaddr, *ifa; int s; char host[NI_MAXHOST]; if (getifaddrs(&ifaddr) == -1) { - warn("Failed to get IP address for interface %s", iface); - return UNKNOWN_STR; + warn("Failed to get IPv4 address for interface %s", iface); + return unknown_str; } for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { @@ -353,8 +313,39 @@ ip(const char *iface) s = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST); if ((strcmp(ifa->ifa_name, iface) == 0) && (ifa->ifa_addr->sa_family == AF_INET)) { if (s != 0) { - warnx("Failed to get IP address for interface %s", iface); - return UNKNOWN_STR; + warnx("Failed to get IPv4 address for interface %s", iface); + return unknown_str; + } + return bprintf("%s", host); + } + } + + freeifaddrs(ifaddr); + + return unknown_str; +} + +static const char * +ipv6(const char *iface) +{ + struct ifaddrs *ifaddr, *ifa; + int s; + char host[NI_MAXHOST]; + + if (getifaddrs(&ifaddr) == -1) { + warn("Failed to get IPv6 address for interface %s", iface); + return unknown_str; + } + + for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { + if (ifa->ifa_addr == NULL) { + continue; + } + s = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in6), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST); + if ((strcmp(ifa->ifa_name, iface) == 0) && (ifa->ifa_addr->sa_family == AF_INET6)) { + if (s != 0) { + warnx("Failed to get IPv6 address for interface %s", iface); + return unknown_str; } return bprintf("%s", host); } @@ -362,7 +353,7 @@ ip(const char *iface) freeifaddrs(ifaddr); - return UNKNOWN_STR; + return unknown_str; } static const char * @@ -371,7 +362,7 @@ kernel_release(void) struct utsname udata; if (uname(&udata) < 0) { - return UNKNOWN_STR; + return unknown_str; } return bprintf("%s", udata.release); @@ -380,9 +371,15 @@ kernel_release(void) static const char * keyboard_indicators(void) { + Display *dpy = XOpenDisplay(NULL); XKeyboardState state; + if (dpy == NULL) { + warnx("XOpenDisplay failed"); + return unknown_str; + } XGetKeyboardControl(dpy, &state); + XCloseDisplay(dpy); switch (state.led_mask) { case 1: @@ -403,7 +400,7 @@ load_avg(void) if (getloadavg(avgs, 3) < 0) { warnx("Failed to get the load avg"); - return UNKNOWN_STR; + return unknown_str; } return bprintf("%.2f %.2f %.2f", avgs[0], avgs[1], avgs[2]); @@ -418,7 +415,7 @@ num_files(const char *dir) if ((fd = opendir(dir)) == NULL) { warn("Failed to get number of files in directory %s", dir); - return UNKNOWN_STR; + return unknown_str; } while ((dp = readdir(fd)) != NULL) { @@ -436,92 +433,48 @@ static const char * ram_free(void) { long free; - FILE *fp; - int n; - - fp = fopen("/proc/meminfo", "r"); - if (fp == NULL) { - warn("Failed to open file /proc/meminfo"); - return UNKNOWN_STR; - } - n = fscanf(fp, "MemFree: %ld kB\n", &free); - fclose(fp); - if (n != 1) - return UNKNOWN_STR; - return bprintf("%f", (float)free / 1024 / 1024); + return (pscanf("/proc/meminfo", "MemFree: %ld kB\n", &free) == 1) ? + bprintf("%f", (float)free / 1024 / 1024) : unknown_str; } static const char * ram_perc(void) { long total, free, buffers, cached; - FILE *fp; - fp = fopen("/proc/meminfo", "r"); - if (fp == NULL) { - warn("Failed to open file /proc/meminfo"); - return UNKNOWN_STR; - } - if (fscanf(fp, "MemTotal: %ld kB\n", &total) != 1 || - fscanf(fp, "MemFree: %ld kB\n", &free) != 1 || - fscanf(fp, "MemAvailable: %ld kB\nBuffers: %ld kB\n", - &buffers, &buffers) != 2 || - fscanf(fp, "Cached: %ld kB\n", &cached) != 1) - goto scanerr; - fclose(fp); - - return bprintf("%d", 100 * ((total - free) - (buffers + cached)) / total); - -scanerr: - fclose(fp); - return UNKNOWN_STR; + return (pscanf("/proc/meminfo", + "MemTotal: %ld kB\n" + "MemFree: %ld kB\n" + "MemAvailable: %ld kB\nBuffers: %ld kB\n" + "Cached: %ld kB\n", + &total, &free, &buffers, &buffers, &cached) == 5) ? + bprintf("%d", 100 * ((total - free) - (buffers + cached)) / total) : + unknown_str; } static const char * ram_total(void) { long total; - FILE *fp; - int n; - fp = fopen("/proc/meminfo", "r"); - if (fp == NULL) { - warn("Failed to open file /proc/meminfo"); - return UNKNOWN_STR; - } - n = fscanf(fp, "MemTotal: %ld kB\n", &total); - fclose(fp); - if (n != 1) - return UNKNOWN_STR; - - return bprintf("%f", (float)total / 1024 / 1024); + return (pscanf("/proc/meminfo", "MemTotal: %ld kB\n", &total) == 1) ? + bprintf("%f", (float)total / 1024 / 1024) : unknown_str; } static const char * ram_used(void) { - long free, total, buffers, cached; - FILE *fp; - - fp = fopen("/proc/meminfo", "r"); - if (fp == NULL) { - warn("Failed to open file /proc/meminfo"); - return UNKNOWN_STR; - } - if (fscanf(fp, "MemTotal: %ld kB\n", &total) != 1 || - fscanf(fp, "MemFree: %ld kB\n", &free) != 1 || - fscanf(fp, "MemAvailable: %ld kB\nBuffers: %ld kB\n", - &buffers, &buffers) != 2 || - fscanf(fp, "Cached: %ld kB\n", &cached) != 1) - goto scanerr; - fclose(fp); - - return bprintf("%f", (float)(total - free - buffers - cached) / 1024 / 1024); + long total, free, buffers, cached; -scanerr: - fclose(fp); - return UNKNOWN_STR; + return (pscanf("/proc/meminfo", + "MemTotal: %ld kB\n" + "MemFree: %ld kB\n" + "MemAvailable: %ld kB\nBuffers: %ld kB\n" + "Cached: %ld kB\n", + &total, &free, &buffers, &buffers, &cached) == 5) ? + bprintf("%f", (float)(total - free - buffers - cached) / 1024 / 1024) : + unknown_str; } static const char * @@ -533,16 +486,16 @@ run_command(const char *cmd) fp = popen(cmd, "r"); if (fp == NULL) { warn("Failed to get command output for %s", cmd); - return UNKNOWN_STR; + return unknown_str; } p = fgets(buf, sizeof(buf) - 1, fp); pclose(fp); if (!p) - return UNKNOWN_STR; + return unknown_str; if ((p = strrchr(buf, '\n')) != NULL) p[0] = '\0'; - return buf[0] ? buf : UNKNOWN_STR; + return buf[0] ? buf : unknown_str; } static const char * @@ -556,22 +509,22 @@ swap_free(void) fp = fopen("/proc/meminfo", "r"); if (fp == NULL) { warn("Failed to open file /proc/meminfo"); - return UNKNOWN_STR; + return unknown_str; } if ((bytes_read = fread(buf, sizeof(char), sizeof(buf) - 1, fp)) == 0) { warn("swap_free: read error"); fclose(fp); - return UNKNOWN_STR; + return unknown_str; } fclose(fp); if ((match = strstr(buf, "SwapTotal")) == NULL) - return UNKNOWN_STR; + return unknown_str; sscanf(match, "SwapTotal: %ld kB\n", &total); if ((match = strstr(buf, "SwapFree")) == NULL) - return UNKNOWN_STR; + return unknown_str; sscanf(match, "SwapFree: %ld kB\n", &free); return bprintf("%f", (float)free / 1024 / 1024); @@ -588,26 +541,26 @@ swap_perc(void) fp = fopen("/proc/meminfo", "r"); if (fp == NULL) { warn("Failed to open file /proc/meminfo"); - return UNKNOWN_STR; + return unknown_str; } if ((bytes_read = fread(buf, sizeof(char), sizeof(buf) - 1, fp)) == 0) { warn("swap_perc: read error"); fclose(fp); - return UNKNOWN_STR; + return unknown_str; } fclose(fp); if ((match = strstr(buf, "SwapTotal")) == NULL) - return UNKNOWN_STR; + return unknown_str; sscanf(match, "SwapTotal: %ld kB\n", &total); if ((match = strstr(buf, "SwapCached")) == NULL) - return UNKNOWN_STR; + return unknown_str; sscanf(match, "SwapCached: %ld kB\n", &cached); if ((match = strstr(buf, "SwapFree")) == NULL) - return UNKNOWN_STR; + return unknown_str; sscanf(match, "SwapFree: %ld kB\n", &free); return bprintf("%d", 100 * (total - free - cached) / total); @@ -624,17 +577,17 @@ swap_total(void) fp = fopen("/proc/meminfo", "r"); if (fp == NULL) { warn("Failed to open file /proc/meminfo"); - return UNKNOWN_STR; + return unknown_str; } if ((bytes_read = fread(buf, sizeof(char), sizeof(buf) - 1, fp)) == 0) { warn("swap_total: read error"); fclose(fp); - return UNKNOWN_STR; + return unknown_str; } fclose(fp); if ((match = strstr(buf, "SwapTotal")) == NULL) - return UNKNOWN_STR; + return unknown_str; sscanf(match, "SwapTotal: %ld kB\n", &total); return bprintf("%f", (float)total / 1024 / 1024); @@ -651,25 +604,25 @@ swap_used(void) fp = fopen("/proc/meminfo", "r"); if (fp == NULL) { warn("Failed to open file /proc/meminfo"); - return UNKNOWN_STR; + return unknown_str; } if ((bytes_read = fread(buf, sizeof(char), sizeof(buf) - 1, fp)) == 0) { warn("swap_used: read error"); fclose(fp); - return UNKNOWN_STR; + return unknown_str; } fclose(fp); if ((match = strstr(buf, "SwapTotal")) == NULL) - return UNKNOWN_STR; + return unknown_str; sscanf(match, "SwapTotal: %ld kB\n", &total); if ((match = strstr(buf, "SwapCached")) == NULL) - return UNKNOWN_STR; + return unknown_str; sscanf(match, "SwapCached: %ld kB\n", &cached); if ((match = strstr(buf, "SwapFree")) == NULL) - return UNKNOWN_STR; + return unknown_str; sscanf(match, "SwapFree: %ld kB\n", &free); return bprintf("%f", (float)(total - free - cached) / 1024 / 1024); @@ -678,20 +631,10 @@ swap_used(void) static const char * temp(const char *file) { - int n, temp; - FILE *fp; + int temp; - fp = fopen(file, "r"); - if (fp == NULL) { - warn("Failed to open file %s", file); - return UNKNOWN_STR; - } - n = fscanf(fp, "%d", &temp); - fclose(fp); - if (n != 1) - return UNKNOWN_STR; - - return bprintf("%d", temp / 1000); + return (pscanf(file, "%d", &temp) == 1) ? + bprintf("%d", temp / 1000) : unknown_str; } static const char * @@ -715,7 +658,7 @@ username(void) if (pw == NULL) { warn("Failed to get username"); - return UNKNOWN_STR; + return unknown_str; } return bprintf("%s", pw->pw_name); @@ -738,20 +681,20 @@ vol_perc(const char *card) afd = open(card, O_RDONLY | O_NONBLOCK); if (afd == -1) { warn("Cannot open %s", card); - return UNKNOWN_STR; + return unknown_str; } if (ioctl(afd, SOUND_MIXER_READ_DEVMASK, &devmask) == -1) { warn("Cannot get volume for %s", card); close(afd); - return UNKNOWN_STR; + return unknown_str; } for (i = 0; i < LEN(vnames); i++) { if (devmask & (1 << i) && !strcmp("vol", vnames[i])) { if (ioctl(afd, MIXER_READ(i), &v) == -1) { warn("vol_perc: ioctl"); close(afd); - return UNKNOWN_STR; + return unknown_str; } } } @@ -774,18 +717,18 @@ wifi_perc(const char *iface) fp = fopen(path, "r"); if (fp == NULL) { warn("Failed to open file %s", path); - return UNKNOWN_STR; + return unknown_str; } p = fgets(status, 5, fp); fclose(fp); if(!p || strcmp(status, "up\n") != 0) { - return UNKNOWN_STR; + return unknown_str; } fp = fopen("/proc/net/wireless", "r"); if (fp == NULL) { warn("Failed to open file /proc/net/wireless"); - return UNKNOWN_STR; + return unknown_str; } for (i = 0; i < 3; i++) { @@ -794,10 +737,10 @@ wifi_perc(const char *iface) } fclose(fp); if (i < 2 || !p) - return UNKNOWN_STR; + return unknown_str; if ((datastart = strstr(buf, iface)) == NULL) - return UNKNOWN_STR; + return unknown_str; datastart = (datastart+(strlen(iface)+1)); sscanf(datastart + 1, " %*d %d %*d %*d %*d %*d %*d %*d %*d %*d", &perc); @@ -818,28 +761,34 @@ wifi_essid(const char *iface) if (sockfd == -1) { warn("Failed to get ESSID for interface %s", iface); - return UNKNOWN_STR; + return unknown_str; } wreq.u.essid.pointer = id; if (ioctl(sockfd,SIOCGIWESSID, &wreq) == -1) { warn("Failed to get ESSID for interface %s", iface); - return UNKNOWN_STR; + return unknown_str; } close(sockfd); if (strcmp(id, "") == 0) - return UNKNOWN_STR; + return unknown_str; else return id; } static void -sighandler(const int signo) +terminate(const int signo) { - if (signo == SIGTERM || signo == SIGINT) { - done = 1; - } + done = 1; +} + +static void +difftimespec(struct timespec *res, struct timespec *a, struct timespec *b) +{ + res->tv_sec = a->tv_sec - b->tv_sec - (a->tv_nsec < b->tv_nsec); + res->tv_nsec = a->tv_nsec - b->tv_nsec + + (a->tv_nsec < b->tv_nsec) * 1000000000; } static void @@ -852,12 +801,11 @@ usage(void) int main(int argc, char *argv[]) { - struct arg argument; struct sigaction act; + struct timespec start, current, diff, intspec, wait; size_t i, len; int sflag = 0; - char status_string[MAXLEN]; - char *element; + char status[MAXLEN]; ARGBEGIN { case 's': @@ -872,48 +820,46 @@ main(int argc, char *argv[]) } memset(&act, 0, sizeof(act)); - act.sa_handler = sighandler; - sigaction(SIGINT, &act, 0); - sigaction(SIGTERM, &act, 0); + act.sa_handler = terminate; + sigaction(SIGINT, &act, NULL); + sigaction(SIGTERM, &act, NULL); - if (!sflag) { - dpy = XOpenDisplay(NULL); - if (!dpy) { - fprintf(stderr, "slstatus: cannot open display"); - exit(1); - } + if (!sflag && !(dpy = XOpenDisplay(NULL))) { + fprintf(stderr, "slstatus: cannot open display"); + return 1; } - setlocale(LC_ALL, ""); - while (!done) { - status_string[0] = '\0'; - - for (element = status_string, i = len = 0; i < LEN(args); - ++i, element += len) { - argument = args[i]; - len = snprintf(element, sizeof(status_string)-1 - len, - argument.fmt, - argument.func(argument.args)); - if (len >= sizeof(status_string)) { - status_string[sizeof(status_string)-1] = '\0'; - break; + clock_gettime(CLOCK_MONOTONIC, &start); + + status[0] = '\0'; + for (i = len = 0; i < LEN(args); i++) { + len += snprintf(status + len, sizeof(status) - len, + args[i].fmt, args[i].func(args[i].args)); + + if (len >= sizeof(status)) { + status[sizeof(status) - 1] = '\0'; } } if (sflag) { - printf("%s\n", status_string); + printf("%s\n", status); } else { - XStoreName(dpy, DefaultRootWindow(dpy), status_string); + XStoreName(dpy, DefaultRootWindow(dpy), status); XSync(dpy, False); } - if ((UPDATE_INTERVAL - delay) <= 0) { - delay = 0; - continue; - } else { - sleep(UPDATE_INTERVAL - delay); - delay = 0; + if (!done) { + clock_gettime(CLOCK_MONOTONIC, ¤t); + difftimespec(&diff, ¤t, &start); + + intspec.tv_sec = interval / 1000; + intspec.tv_nsec = (interval % 1000) * 1000000; + difftimespec(&wait, &intspec, &diff); + + if (wait.tv_sec >= 0) { + nanosleep(&wait, NULL); + } } }