fix double free bug, simplify error handling, reduce X11 calls, improve style

This commit is contained in:
MvA 2022-08-31 18:21:52 +02:00 committed by Dan Cross
parent 52be2761ae
commit 3e764832bc

View file

@ -24,6 +24,7 @@ struct Win {
XDisplay *dpy; XDisplay *dpy;
XWindow root; XWindow root;
Atom net_active_window; Atom net_active_window;
Reprog *exclude = nil; Reprog *exclude = nil;
Win *win; Win *win;
@ -36,14 +37,13 @@ int showwmnames;
Font *font; Font *font;
Image *lightblue; Image *lightblue;
XErrorHandler oldxerrorhandler;
enum { enum
{
PAD = 3, PAD = 3,
MARGIN = 5 MARGIN = 5
}; };
static jmp_buf savebuf;
int int
winwatchxerrorhandler(XDisplay *disp, XErrorEvent *xe) winwatchxerrorhandler(XDisplay *disp, XErrorEvent *xe)
@ -53,11 +53,7 @@ winwatchxerrorhandler(XDisplay *disp, XErrorEvent *xe)
XGetErrorText(disp, xe->error_code, buf, 100); XGetErrorText(disp, xe->error_code, buf, 100);
fprint(2, "winwatch: X error %s, request code %d\n", fprint(2, "winwatch: X error %s, request code %d\n",
buf, xe->request_code); buf, xe->request_code);
XFlush(disp); return 0;
XSync(disp, False);
XSetErrorHandler(oldxerrorhandler);
longjmp(savebuf, 1);
return(0); /* Not reached */
} }
void* void*
@ -75,7 +71,7 @@ estrdup(char *s)
s = strdup(s); s = strdup(s);
if(s == nil) if(s == nil)
sysfatal("out of memory allocating"); sysfatal("out of memory allocating");
return(s); return s;
} }
char* char*
@ -89,18 +85,15 @@ getproperty(XWindow w, Atom a)
n = 100; n = 100;
p = nil; p = nil;
oldxerrorhandler = XSetErrorHandler(winwatchxerrorhandler);
s = XGetWindowProperty(dpy, w, a, 0, 100L, 0, s = XGetWindowProperty(dpy, w, a, 0, 100L, 0,
AnyPropertyType, &type, &fmt, &n, &dummy, &p); AnyPropertyType, &type, &fmt, &n, &dummy, &p);
XFlush(dpy);
XSync(dpy, False);
XSetErrorHandler(oldxerrorhandler);
if(s != 0){ if(s != 0){
XFree(p); XFree(p);
return(nil); return nil;
} }
return((char*)p); return (char*)p;
} }
XWindow XWindow
@ -108,7 +101,7 @@ findname(XWindow w)
{ {
int i; int i;
uint nxwin; uint nxwin;
XWindow dw1, dw2, *xwin; XWindow dw1, dw2, *xwin, rwin;
char *p; char *p;
int s; int s;
Atom net_wm_name; Atom net_wm_name;
@ -116,37 +109,32 @@ findname(XWindow w)
p = getproperty(w, XA_WM_NAME); p = getproperty(w, XA_WM_NAME);
if(p){ if(p){
free(p); free(p);
return(w); return w;
} }
net_wm_name = XInternAtom(dpy, "_NET_WM_NAME", FALSE); net_wm_name = XInternAtom(dpy, "_NET_WM_NAME", FALSE);
p = getproperty(w, net_wm_name); p = getproperty(w, net_wm_name);
if(p){ if(p){
free(p); free(p);
return(w); return w;
} }
oldxerrorhandler = XSetErrorHandler(winwatchxerrorhandler); rwin = 0;
s = XQueryTree(dpy, w, &dw1, &dw2, &xwin, &nxwin); s = XQueryTree(dpy, w, &dw1, &dw2, &xwin, &nxwin);
XFlush(dpy);
XSync(dpy, False);
XSetErrorHandler(oldxerrorhandler);
if(s == 0) {
if (xwin != NULL)
XFree(xwin);
return 0;
}
if(s != 0){
for (i = 0; i < nxwin; i++){ for (i = 0; i < nxwin; i++){
w = findname(xwin[i]); w = findname(xwin[i]);
if(w != 0){ if(w != 0){
XFree(xwin); rwin = w;
return w; break ;
} }
} }
XFree(xwin); XFree(xwin);
}
return 0; return rwin;
} }
int int
@ -156,7 +144,6 @@ wcmp(const void *w1, const void *w2)
} }
/* unicode-aware case-insensitive strcmp, taken from golangs gc/subr.c */ /* unicode-aware case-insensitive strcmp, taken from golangs gc/subr.c */
int int
_cistrcmp(char *p, char *q) _cistrcmp(char *p, char *q)
{ {
@ -200,17 +187,14 @@ refreshwin(void)
Status s; Status s;
Atom net_wm_name; Atom net_wm_name;
oldxerrorhandler = XSetErrorHandler(winwatchxerrorhandler);
s = XQueryTree(dpy, root, &dw1, &dw2, &xwin, &nxwin); s = XQueryTree(dpy, root, &dw1, &dw2, &xwin, &nxwin);
XFlush(dpy);
XSync(dpy, False);
XSetErrorHandler(oldxerrorhandler);
if(s == 0){ if(s == 0){
if(xwin != NULL) if(xwin != NULL)
XFree(xwin); XFree(xwin);
return; return;
} }
qsort(xwin, nxwin, sizeof(xwin[0]), wcmp); qsort(xwin, nxwin, sizeof(xwin[0]), wcmp);
nw = 0; nw = 0;
@ -220,11 +204,8 @@ refreshwin(void)
if(xwin[i] == 0) if(xwin[i] == 0)
continue; continue;
oldxerrorhandler = XSetErrorHandler(winwatchxerrorhandler);
s = XGetWindowAttributes(dpy, xwin[i], &attr); s = XGetWindowAttributes(dpy, xwin[i], &attr);
XFlush(dpy);
XSync(dpy, False);
XSetErrorHandler(oldxerrorhandler);
if(s == 0) if(s == 0)
continue; continue;
if(attr.width <= 0 || if(attr.width <= 0 ||
@ -232,11 +213,7 @@ refreshwin(void)
attr.map_state != IsViewable) attr.map_state != IsViewable)
continue; continue;
oldxerrorhandler = XSetErrorHandler(winwatchxerrorhandler);
s = XGetClassHint(dpy, xwin[i], &class); s = XGetClassHint(dpy, xwin[i], &class);
XFlush(dpy);
XSync(dpy, False);
XSetErrorHandler(oldxerrorhandler);
if(s == 0) if(s == 0)
continue; continue;
@ -280,6 +257,7 @@ refreshwin(void)
mwin += 8; mwin += 8;
win = erealloc(win, mwin * sizeof(win[0])); win = erealloc(win, mwin * sizeof(win[0]));
} }
win[nw].n = xwin[i]; win[nw].n = xwin[i];
win[nw].label = estrdup(label); win[nw].label = estrdup(label);
win[nw].dirty = 1; win[nw].dirty = 1;
@ -290,11 +268,7 @@ refreshwin(void)
nw++; nw++;
} }
oldxerrorhandler = XSetErrorHandler(winwatchxerrorhandler);
XFree(xwin); XFree(xwin);
XFlush(dpy);
XSync(dpy, False);
XSetErrorHandler(oldxerrorhandler);
while(nwin > nw) while(nwin > nw)
free(win[--nwin].label); free(win[--nwin].label);
@ -481,9 +455,6 @@ main(int argc, char **argv)
if(argc) if(argc)
usage(); usage();
/* moved up from original winwatch.c for p9p because there can be only one but we want to restart when needed */
einit(Emouse | Ekeyboard);
Etimer = etimer(0, 1000);
dpy = XOpenDisplay(""); dpy = XOpenDisplay("");
if(dpy == nil) if(dpy == nil)
@ -500,11 +471,14 @@ main(int argc, char **argv)
if(font == nil) if(font == nil)
sysfatal("font '%s' not found", fontname); sysfatal("font '%s' not found", fontname);
/* reentry point upon X server errors */ einit(Emouse | Ekeyboard);
setjmp(savebuf); Etimer = etimer(0, 1000);
XSetErrorHandler(winwatchxerrorhandler);
refreshwin(); refreshwin();
redraw(screen, 1); redraw(screen, 1);
for(;;){ for(;;){
switch(eread(Emouse|Ekeyboard|Etimer, &e)){ switch(eread(Emouse|Ekeyboard|Etimer, &e)){
case Ekeyboard: case Ekeyboard: