aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFRIGN <dev@frign.de>2016-09-11 23:08:19 +0200
committerMarkus Teich <markus.teich@stusta.mhn.de>2016-09-23 18:39:01 +0200
commitb00f444a4ea0d9ffa5cd7dcda71c97cdf05d322e (patch)
tree70941ff297d2257a52621884f64af9cbfa364b52
parentcd3c546c37d91e24b8c55bab88bfcb920d8ea895 (diff)
Remove cleanup and deglobalize and rework data structures
The cleanup removal is a joint-venture with Markus. We assume the X server does the cleanup, so we don't need it. The idea is that the fds are closed at exit and thus already indicate to the X server that the client has quit. Analogously the same applies to freeing memory sections previously allocated for the X server. We love XXXXXL burgers and therefore removed XUngrabPointer XUngrabKeyboard XFreeColors XFreePixmap XDestroyWindow Lines of Code. For a project like slock there is no need to carry around global state. By moving the three structures to main() it is now clear which functions modify which state, greatly improving the readability of the code, especially given slock is a suid program.
-rw-r--r--slock.c78
1 files changed, 23 insertions, 55 deletions
diff --git a/slock.c b/slock.c
index 7127ebe..f423f8c 100644
--- a/slock.c
+++ b/slock.c
@@ -33,18 +33,18 @@ enum {
33 33
34#include "config.h" 34#include "config.h"
35 35
36typedef struct { 36struct lock {
37 int screen; 37 int screen;
38 Window root, win; 38 Window root, win;
39 Pixmap pmap; 39 Pixmap pmap;
40 unsigned long colors[NUMCOLS]; 40 unsigned long colors[NUMCOLS];
41} Lock; 41};
42 42
43static Lock **locks; 43struct xrandr {
44static int nscreens; 44 int active;
45static Bool rr; 45 int evbase;
46static int rrevbase; 46 int errbase;
47static int rrerrbase; 47};
48 48
49static void 49static void
50die(const char *errstr, ...) 50die(const char *errstr, ...)
@@ -123,7 +123,8 @@ getpw(void)
123} 123}
124 124
125static void 125static void
126readpw(Display *dpy, const char *pws) 126readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens,
127 const char *pws)
127{ 128{
128 char buf[32], passwd[256], *encrypted; 129 char buf[32], passwd[256], *encrypted;
129 int num, screen, running, failure; 130 int num, screen, running, failure;
@@ -194,7 +195,7 @@ readpw(Display *dpy, const char *pws)
194 } 195 }
195 oldc = color; 196 oldc = color;
196 } 197 }
197 } else if (rr && ev.type == rrevbase + RRScreenChangeNotify) { 198 } else if (rr->active && ev.type == rr->evbase + RRScreenChangeNotify) {
198 XRRScreenChangeNotifyEvent *rre = (XRRScreenChangeNotifyEvent*)&ev; 199 XRRScreenChangeNotifyEvent *rre = (XRRScreenChangeNotifyEvent*)&ev;
199 for (screen = 0; screen < nscreens; screen++) { 200 for (screen = 0; screen < nscreens; screen++) {
200 if (locks[screen]->win == rre->window) { 201 if (locks[screen]->win == rre->window) {
@@ -207,44 +208,17 @@ readpw(Display *dpy, const char *pws)
207 } 208 }
208} 209}
209 210
210static void 211static struct lock *
211unlockscreen(Display *dpy, Lock *lock) 212lockscreen(Display *dpy, struct xrandr *rr, int screen)
212{
213 if(dpy == NULL || lock == NULL)
214 return;
215
216 XUngrabPointer(dpy, CurrentTime);
217 XUngrabKeyboard(dpy, CurrentTime);
218 XFreeColors(dpy, DefaultColormap(dpy, lock->screen), lock->colors, NUMCOLS, 0);
219 XFreePixmap(dpy, lock->pmap);
220 XDestroyWindow(dpy, lock->win);
221
222 free(lock);
223}
224
225static void
226cleanup(Display *dpy)
227{
228 int s;
229
230 for (s = 0; s < nscreens; ++s)
231 unlockscreen(dpy, locks[s]);
232
233 free(locks);
234 XCloseDisplay(dpy);
235}
236
237static Lock *
238lockscreen(Display *dpy, int screen)
239{ 213{
240 char curs[] = {0, 0, 0, 0, 0, 0, 0, 0}; 214 char curs[] = {0, 0, 0, 0, 0, 0, 0, 0};
241 int i, ptgrab, kbgrab; 215 int i, ptgrab, kbgrab;
242 Lock *lock; 216 struct lock *lock;
243 XColor color, dummy; 217 XColor color, dummy;
244 XSetWindowAttributes wa; 218 XSetWindowAttributes wa;
245 Cursor invisible; 219 Cursor invisible;
246 220
247 if (dpy == NULL || screen < 0 || !(lock = malloc(sizeof(Lock)))) 221 if (dpy == NULL || screen < 0 || !(lock = malloc(sizeof(struct lock))))
248 return NULL; 222 return NULL;
249 223
250 lock->screen = screen; 224 lock->screen = screen;
@@ -281,7 +255,7 @@ lockscreen(Display *dpy, int screen)
281 /* input is grabbed: we can lock the screen */ 255 /* input is grabbed: we can lock the screen */
282 if (ptgrab == GrabSuccess && kbgrab == GrabSuccess) { 256 if (ptgrab == GrabSuccess && kbgrab == GrabSuccess) {
283 XMapRaised(dpy, lock->win); 257 XMapRaised(dpy, lock->win);
284 if (rr) 258 if (rr->active)
285 XRRSelectInput(dpy, lock->win, RRScreenChangeNotifyMask); 259 XRRSelectInput(dpy, lock->win, RRScreenChangeNotifyMask);
286 260
287 XSelectInput(dpy, lock->root, SubstructureNotifyMask); 261 XSelectInput(dpy, lock->root, SubstructureNotifyMask);
@@ -312,13 +286,15 @@ usage(void)
312 286
313int 287int
314main(int argc, char **argv) { 288main(int argc, char **argv) {
289 struct xrandr rr;
290 struct lock **locks;
315 struct passwd *pwd; 291 struct passwd *pwd;
316 struct group *grp; 292 struct group *grp;
317 uid_t duid; 293 uid_t duid;
318 gid_t dgid; 294 gid_t dgid;
319 const char *pws; 295 const char *pws;
320 Display *dpy; 296 Display *dpy;
321 int s, nlocks; 297 int s, nlocks, nscreens;
322 298
323 ARGBEGIN { 299 ARGBEGIN {
324 case 'v': 300 case 'v':
@@ -360,16 +336,14 @@ main(int argc, char **argv) {
360 die("slock: setuid: %s\n", strerror(errno)); 336 die("slock: setuid: %s\n", strerror(errno));
361 337
362 /* check for Xrandr support */ 338 /* check for Xrandr support */
363 rr = XRRQueryExtension(dpy, &rrevbase, &rrerrbase); 339 rr.active = XRRQueryExtension(dpy, &rr.evbase, &rr.errbase);
364 340
365 /* get number of screens in display "dpy" and blank them */ 341 /* get number of screens in display "dpy" and blank them */
366 nscreens = ScreenCount(dpy); 342 nscreens = ScreenCount(dpy);
367 if (!(locks = calloc(nscreens, sizeof(Lock *)))) { 343 if (!(locks = calloc(nscreens, sizeof(struct lock *))))
368 XCloseDisplay(dpy);
369 die("slock: out of memory\n"); 344 die("slock: out of memory\n");
370 }
371 for (nlocks = 0, s = 0; s < nscreens; s++) { 345 for (nlocks = 0, s = 0; s < nscreens; s++) {
372 if ((locks[s] = lockscreen(dpy, s)) != NULL) 346 if ((locks[s] = lockscreen(dpy, &rr, s)) != NULL)
373 nlocks++; 347 nlocks++;
374 else 348 else
375 break; 349 break;
@@ -377,16 +351,13 @@ main(int argc, char **argv) {
377 XSync(dpy, 0); 351 XSync(dpy, 0);
378 352
379 /* did we manage to lock everything? */ 353 /* did we manage to lock everything? */
380 if (nlocks != nscreens) { 354 if (nlocks != nscreens)
381 cleanup(dpy);
382 return 1; 355 return 1;
383 }
384 356
385 /* run post-lock command */ 357 /* run post-lock command */
386 if (argc > 0) { 358 if (argc > 0) {
387 switch (fork()) { 359 switch (fork()) {
388 case -1: 360 case -1:
389 cleanup(dpy);
390 die("slock: fork failed: %s\n", strerror(errno)); 361 die("slock: fork failed: %s\n", strerror(errno));
391 case 0: 362 case 0:
392 if (close(ConnectionNumber(dpy)) < 0) 363 if (close(ConnectionNumber(dpy)) < 0)
@@ -399,10 +370,7 @@ main(int argc, char **argv) {
399 } 370 }
400 371
401 /* everything is now blank. Wait for the correct password */ 372 /* everything is now blank. Wait for the correct password */
402 readpw(dpy, pws); 373 readpw(dpy, &rr, locks, nscreens, pws);
403
404 /* password ok, unlock everything and quit */
405 cleanup(dpy);
406 374
407 return 0; 375 return 0;
408} 376}