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.
This commit is contained in:
parent
cd3c546c37
commit
b00f444a4e
78
slock.c
78
slock.c
|
@ -33,18 +33,18 @@ enum {
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
typedef struct {
|
struct lock {
|
||||||
int screen;
|
int screen;
|
||||||
Window root, win;
|
Window root, win;
|
||||||
Pixmap pmap;
|
Pixmap pmap;
|
||||||
unsigned long colors[NUMCOLS];
|
unsigned long colors[NUMCOLS];
|
||||||
} Lock;
|
};
|
||||||
|
|
||||||
static Lock **locks;
|
struct xrandr {
|
||||||
static int nscreens;
|
int active;
|
||||||
static Bool rr;
|
int evbase;
|
||||||
static int rrevbase;
|
int errbase;
|
||||||
static int rrerrbase;
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
die(const char *errstr, ...)
|
die(const char *errstr, ...)
|
||||||
|
@ -123,7 +123,8 @@ getpw(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
readpw(Display *dpy, const char *pws)
|
readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens,
|
||||||
|
const char *pws)
|
||||||
{
|
{
|
||||||
char buf[32], passwd[256], *encrypted;
|
char buf[32], passwd[256], *encrypted;
|
||||||
int num, screen, running, failure;
|
int num, screen, running, failure;
|
||||||
|
@ -194,7 +195,7 @@ readpw(Display *dpy, const char *pws)
|
||||||
}
|
}
|
||||||
oldc = color;
|
oldc = color;
|
||||||
}
|
}
|
||||||
} else if (rr && ev.type == rrevbase + RRScreenChangeNotify) {
|
} else if (rr->active && ev.type == rr->evbase + RRScreenChangeNotify) {
|
||||||
XRRScreenChangeNotifyEvent *rre = (XRRScreenChangeNotifyEvent*)&ev;
|
XRRScreenChangeNotifyEvent *rre = (XRRScreenChangeNotifyEvent*)&ev;
|
||||||
for (screen = 0; screen < nscreens; screen++) {
|
for (screen = 0; screen < nscreens; screen++) {
|
||||||
if (locks[screen]->win == rre->window) {
|
if (locks[screen]->win == rre->window) {
|
||||||
|
@ -207,44 +208,17 @@ readpw(Display *dpy, const char *pws)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static struct lock *
|
||||||
unlockscreen(Display *dpy, Lock *lock)
|
lockscreen(Display *dpy, struct xrandr *rr, int screen)
|
||||||
{
|
|
||||||
if(dpy == NULL || lock == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
XUngrabPointer(dpy, CurrentTime);
|
|
||||||
XUngrabKeyboard(dpy, CurrentTime);
|
|
||||||
XFreeColors(dpy, DefaultColormap(dpy, lock->screen), lock->colors, NUMCOLS, 0);
|
|
||||||
XFreePixmap(dpy, lock->pmap);
|
|
||||||
XDestroyWindow(dpy, lock->win);
|
|
||||||
|
|
||||||
free(lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
cleanup(Display *dpy)
|
|
||||||
{
|
|
||||||
int s;
|
|
||||||
|
|
||||||
for (s = 0; s < nscreens; ++s)
|
|
||||||
unlockscreen(dpy, locks[s]);
|
|
||||||
|
|
||||||
free(locks);
|
|
||||||
XCloseDisplay(dpy);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Lock *
|
|
||||||
lockscreen(Display *dpy, int screen)
|
|
||||||
{
|
{
|
||||||
char curs[] = {0, 0, 0, 0, 0, 0, 0, 0};
|
char curs[] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||||
int i, ptgrab, kbgrab;
|
int i, ptgrab, kbgrab;
|
||||||
Lock *lock;
|
struct lock *lock;
|
||||||
XColor color, dummy;
|
XColor color, dummy;
|
||||||
XSetWindowAttributes wa;
|
XSetWindowAttributes wa;
|
||||||
Cursor invisible;
|
Cursor invisible;
|
||||||
|
|
||||||
if (dpy == NULL || screen < 0 || !(lock = malloc(sizeof(Lock))))
|
if (dpy == NULL || screen < 0 || !(lock = malloc(sizeof(struct lock))))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
lock->screen = screen;
|
lock->screen = screen;
|
||||||
|
@ -281,7 +255,7 @@ lockscreen(Display *dpy, int screen)
|
||||||
/* input is grabbed: we can lock the screen */
|
/* input is grabbed: we can lock the screen */
|
||||||
if (ptgrab == GrabSuccess && kbgrab == GrabSuccess) {
|
if (ptgrab == GrabSuccess && kbgrab == GrabSuccess) {
|
||||||
XMapRaised(dpy, lock->win);
|
XMapRaised(dpy, lock->win);
|
||||||
if (rr)
|
if (rr->active)
|
||||||
XRRSelectInput(dpy, lock->win, RRScreenChangeNotifyMask);
|
XRRSelectInput(dpy, lock->win, RRScreenChangeNotifyMask);
|
||||||
|
|
||||||
XSelectInput(dpy, lock->root, SubstructureNotifyMask);
|
XSelectInput(dpy, lock->root, SubstructureNotifyMask);
|
||||||
|
@ -312,13 +286,15 @@ usage(void)
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv) {
|
main(int argc, char **argv) {
|
||||||
|
struct xrandr rr;
|
||||||
|
struct lock **locks;
|
||||||
struct passwd *pwd;
|
struct passwd *pwd;
|
||||||
struct group *grp;
|
struct group *grp;
|
||||||
uid_t duid;
|
uid_t duid;
|
||||||
gid_t dgid;
|
gid_t dgid;
|
||||||
const char *pws;
|
const char *pws;
|
||||||
Display *dpy;
|
Display *dpy;
|
||||||
int s, nlocks;
|
int s, nlocks, nscreens;
|
||||||
|
|
||||||
ARGBEGIN {
|
ARGBEGIN {
|
||||||
case 'v':
|
case 'v':
|
||||||
|
@ -360,16 +336,14 @@ main(int argc, char **argv) {
|
||||||
die("slock: setuid: %s\n", strerror(errno));
|
die("slock: setuid: %s\n", strerror(errno));
|
||||||
|
|
||||||
/* check for Xrandr support */
|
/* check for Xrandr support */
|
||||||
rr = XRRQueryExtension(dpy, &rrevbase, &rrerrbase);
|
rr.active = XRRQueryExtension(dpy, &rr.evbase, &rr.errbase);
|
||||||
|
|
||||||
/* get number of screens in display "dpy" and blank them */
|
/* get number of screens in display "dpy" and blank them */
|
||||||
nscreens = ScreenCount(dpy);
|
nscreens = ScreenCount(dpy);
|
||||||
if (!(locks = calloc(nscreens, sizeof(Lock *)))) {
|
if (!(locks = calloc(nscreens, sizeof(struct lock *))))
|
||||||
XCloseDisplay(dpy);
|
|
||||||
die("slock: out of memory\n");
|
die("slock: out of memory\n");
|
||||||
}
|
|
||||||
for (nlocks = 0, s = 0; s < nscreens; s++) {
|
for (nlocks = 0, s = 0; s < nscreens; s++) {
|
||||||
if ((locks[s] = lockscreen(dpy, s)) != NULL)
|
if ((locks[s] = lockscreen(dpy, &rr, s)) != NULL)
|
||||||
nlocks++;
|
nlocks++;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
|
@ -377,16 +351,13 @@ main(int argc, char **argv) {
|
||||||
XSync(dpy, 0);
|
XSync(dpy, 0);
|
||||||
|
|
||||||
/* did we manage to lock everything? */
|
/* did we manage to lock everything? */
|
||||||
if (nlocks != nscreens) {
|
if (nlocks != nscreens)
|
||||||
cleanup(dpy);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
|
|
||||||
/* run post-lock command */
|
/* run post-lock command */
|
||||||
if (argc > 0) {
|
if (argc > 0) {
|
||||||
switch (fork()) {
|
switch (fork()) {
|
||||||
case -1:
|
case -1:
|
||||||
cleanup(dpy);
|
|
||||||
die("slock: fork failed: %s\n", strerror(errno));
|
die("slock: fork failed: %s\n", strerror(errno));
|
||||||
case 0:
|
case 0:
|
||||||
if (close(ConnectionNumber(dpy)) < 0)
|
if (close(ConnectionNumber(dpy)) < 0)
|
||||||
|
@ -399,10 +370,7 @@ main(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* everything is now blank. Wait for the correct password */
|
/* everything is now blank. Wait for the correct password */
|
||||||
readpw(dpy, pws);
|
readpw(dpy, &rr, locks, nscreens, pws);
|
||||||
|
|
||||||
/* password ok, unlock everything and quit */
|
|
||||||
cleanup(dpy);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue