X-Git-Url: https://git.xinqibao.xyz/slstatus.git/blobdiff_plain/178c23e3d2b75a99010987bf3e17a82ff7b83b6a..8f5219b6dab5a1c9b7f92362a34aacfd393fa0e4:/slstatus.c diff --git a/slstatus.c b/slstatus.c index c4a9e92..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 @@ -28,13 +27,14 @@ #include "arg.h" +#define LEN(x) (sizeof (x) / sizeof *(x)) + struct arg { const char *(*func)(); const char *fmt; 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); @@ -48,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); @@ -69,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; @@ -97,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; @@ -153,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 < sizeof(map) / sizeof(*map); i++) { + for (i = 0; i < LEN(map); i++) { if (!strcmp(map[i].state, state)) { break; } } - - return (i == sizeof(map) / sizeof(*map)) ? "?" : map[i].symbol; + return (i == LEN(map)) ? "?" : map[i].symbol; } static const char * cpu_freq(void) { - int n, freq; - FILE *fp; - - 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; + int freq; - 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); } @@ -236,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; } @@ -248,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); @@ -262,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)); @@ -277,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); @@ -290,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); @@ -299,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 * @@ -326,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) { @@ -351,8 +313,8 @@ 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); } @@ -360,7 +322,38 @@ ip(const char *iface) freeifaddrs(ifaddr); - return UNKNOWN_STR; + 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); + } + } + + freeifaddrs(ifaddr); + + return unknown_str; } static const char * @@ -369,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,6 +373,11 @@ keyboard_indicators(void) { Display *dpy = XOpenDisplay(NULL); XKeyboardState state; + + if (dpy == NULL) { + warnx("XOpenDisplay failed"); + return unknown_str; + } XGetKeyboardControl(dpy, &state); XCloseDisplay(dpy); @@ -402,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]); @@ -417,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) { @@ -435,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 * @@ -532,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 * @@ -555,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); @@ -587,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); @@ -623,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); @@ -650,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); @@ -677,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 * @@ -714,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); @@ -737,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 < (sizeof(vnames) / sizeof((vnames[0]))); i++) { + 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; } } } @@ -773,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++) { @@ -793,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); @@ -817,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 @@ -851,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': @@ -871,45 +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 (!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 < sizeof(args) / sizeof(args[0]); - ++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); + } } }