Introduction
Introduction Statistics Contact Development Disclaimer Help
slstatus.c - slstatus - status monitor
git clone git://git.suckless.org/slstatus
Log
Files
Refs
README
LICENSE
---
slstatus.c (2643B)
---
1 /* See LICENSE file for copyright and license details. */
2 #include <errno.h>
3 #include <signal.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <time.h>
8 #include <X11/Xlib.h>
9
10 #include "arg.h"
11 #include "slstatus.h"
12 #include "util.h"
13
14 struct arg {
15 const char *(*func)(const char *);
16 const char *fmt;
17 const char *args;
18 };
19
20 char buf[1024];
21 static volatile sig_atomic_t done;
22 static Display *dpy;
23
24 #include "config.h"
25
26 static void
27 terminate(const int signo)
28 {
29 if (signo != SIGUSR1)
30 done = 1;
31 }
32
33 static void
34 difftimespec(struct timespec *res, struct timespec *a, struct timespec *…
35 {
36 res->tv_sec = a->tv_sec - b->tv_sec - (a->tv_nsec < b->tv_nsec);
37 res->tv_nsec = a->tv_nsec - b->tv_nsec +
38 (a->tv_nsec < b->tv_nsec) * 1E9;
39 }
40
41 static void
42 usage(void)
43 {
44 die("usage: %s [-v] [-s] [-1]", argv0);
45 }
46
47 int
48 main(int argc, char *argv[])
49 {
50 struct sigaction act;
51 struct timespec start, current, diff, intspec, wait;
52 size_t i, len;
53 int sflag, ret;
54 char status[MAXLEN];
55 const char *res;
56
57 sflag = 0;
58 ARGBEGIN {
59 case 'v':
60 die("slstatus-"VERSION);
61 break;
62 case '1':
63 done = 1;
64 /* FALLTHROUGH */
65 case 's':
66 sflag = 1;
67 break;
68 default:
69 usage();
70 } ARGEND
71
72 if (argc)
73 usage();
74
75 memset(&act, 0, sizeof(act));
76 act.sa_handler = terminate;
77 sigaction(SIGINT, &act, NULL);
78 sigaction(SIGTERM, &act, NULL);
79 act.sa_flags |= SA_RESTART;
80 sigaction(SIGUSR1, &act, NULL);
81
82 if (!sflag && !(dpy = XOpenDisplay(NULL)))
83 die("XOpenDisplay: Failed to open display");
84
85 do {
86 if (clock_gettime(CLOCK_MONOTONIC, &start) < 0)
87 die("clock_gettime:");
88
89 status[0] = '\0';
90 for (i = len = 0; i < LEN(args); i++) {
91 if (!(res = args[i].func(args[i].args)))
92 res = unknown_str;
93
94 if ((ret = esnprintf(status + len, sizeof(status…
95 args[i].fmt, res)) < 0)
96 break;
97
98 len += ret;
99 }
100
101 if (sflag) {
102 puts(status);
103 fflush(stdout);
104 if (ferror(stdout))
105 die("puts:");
106 } else {
107 if (XStoreName(dpy, DefaultRootWindow(dpy), stat…
108 die("XStoreName: Allocation failed");
109 XFlush(dpy);
110 }
111
112 if (!done) {
113 if (clock_gettime(CLOCK_MONOTONIC, &current) < 0)
114 die("clock_gettime:");
115 difftimespec(&diff, &current, &start);
116
117 intspec.tv_sec = interval / 1000;
118 intspec.tv_nsec = (interval % 1000) * 1E6;
119 difftimespec(&wait, &intspec, &diff);
120
121 if (wait.tv_sec >= 0 &&
122 nanosleep(&wait, NULL) < 0 &&
123 errno != EINTR)
124 die("nanosleep:");
125 }
126 } while (!done);
127
128 if (!sflag) {
129 XStoreName(dpy, DefaultRootWindow(dpy), NULL);
130 if (XCloseDisplay(dpy) < 0)
131 die("XCloseDisplay: Failed to close display");
132 }
133
134 return 0;
135 }
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.